Java Python Integration
Asked Answered
P

12

58

I have a Java app that needs to integrate with a 3rd party library. The library is written in Python, and I don't have any say over that. I'm trying to figure out the best way to integrate with it. I'm trying out JEPP (Java Embedded Python) - has anyone used that before? My other thought is to use JNI to communicate with the C bindings for Python.

Any thoughts on the best way to do this would be appreciated. Thanks.

Playhouse answered 13/7, 2009 at 14:15 Comment(1)
If the python library is all written in pure python, what about using Jython ?Pricking
D
38

Why not use Jython? The only downside I can immediately think of is if your library uses CPython native extensions.

EDIT: If you can use Jython now but think you may have problems with a later version of the library, I suggest you try to isolate the library from your app (e.g. some sort of adapter interface). Go with the simplest thing that works for the moment, then consider JNI/CPython/etc if and when you ever need to. There's little to be gained by going the (painful) JNI route unless you really have to.

Daukas answered 13/7, 2009 at 14:17 Comment(4)
I've looked at the Jython libraries. The problem is that I have no guarantee that the libraries I'm using don't (or won't in the future) use native extensions.Playhouse
I'll do that. Thanks. Do I need to add anything special to a py file to run it with Jython? Or if it's native python, should it just run?Playhouse
I don't have much experience with Jython - consult the docs :)Daukas
Will do, appreciate the help.Playhouse
O
21

Frankly most ways to somehow run Python directly from within JVM don't work. They are either not-quite-compatible (new release of your third party library can use python 2.6 features and will not work with Jython 2.5) or hacky (it will break with cryptic JVM stacktrace not really leading to solution).

My preferred way to integrate the two would use RPC. XML RPC is not a bad choice here, if you have moderate amounts of data. It is pretty well supported — Python has it in its standard library. Java libraries are also easy to find. Now depending on your setup either Java or Python part would be a server accepting connection from other language.

A less popular but worth considering alternative way to do RPCs is Google protobuffers, which have 2/3 of support for nice rpc. You just need to provide your transport layer. Not that much work and the convenience of writing is reasonable.

Another option is to write a C wrapper around that pieces of Python functionality that you need to expose to Java and use it via JVM native plugins. You can ease the pain by going with SWIG SWIG.

Essentially in your case it works like that:

  1. Create a SWIG interface for all method calls from Java to C++.
  2. Create C/C++ code that will receive your calls and internally call python interpreter with right params.
  3. Convert response you get from python and send it via swig back to your Java code.

This solution is fairly complex, a bit of an overkill in most cases. Still it is worth doing if you (for some reason) cannot afford RPCs. RPC still would be my preferred choice, though.

Omophagia answered 13/7, 2009 at 14:44 Comment(2)
This non-JVM compatibility is the biggest shortcoming of Python. Thats why we decided to use Scala. It is even better.Marita
Marcin, the remote call way is not desireable for big data implementations (algorithms or applications) for performance and scalability reasons. Indeed "not-quite-compatible" is an issue but "break with cryptic JVM stacktrace" requires some explanation and examples please. You mean hard to debug or does not run? I am trying out Jep which does JNI in-process and seems like the best thing. github.com/mrj0/jep/wiki/How-Jep-Works. Thoughts?Arawn
S
21

Many years later, just to add an option which is more popular these days...

If you need CPython functionality, py4j is a good option. py4j has seen seen frequent updates in 2016 2017 2018 2019 2020 and has gained some popularity, because it is used e.g. by Apache Spark to achieve CPython interoperability.

Sestina answered 18/3, 2017 at 15:53 Comment(3)
It's a really better option than Jython, which is a technological dead end and doesn't seem to be maintained anymore.Philippe
The first published version of py4j was in 2009. As of this writing, last published version was in October 2018.Girish
From what I understand, the goal of the OP is to call a Python library from a Java app, and py4j is about "enabling Python programs to dynamically access Java objects in a Java Virtual Machine."Fool
G
8

The best solutions, is to use Python programs throw REST API. You define your services and call them. You perhaps need to learn some new modules. But you will be more flexible for futures changes.

Here a small list of use full modules for this purpose: Python modules

  • Flask
  • Flask-SQLAlchemy
  • Flask-Restful
  • SQlite3
  • Jsonify

Java modules (for calling rest api) Jersey or Apache CXF

You will need a small Learning curve, but later you will get more productivity and modularity and even elasticity...

Giveandtake answered 30/10, 2019 at 11:30 Comment(0)
R
6

My other thought is to use JNI to communicate with the C bindings for Python.

I like very much JNA:

JNA provides Java programs easy access to native shared libraries (DLLs on Windows) without writing anything but Java code—no JNI or native code is required. This functionality is comparable to Windows' Platform/Invoke and Python's ctypes. Access is dynamic at runtime without code generation.

My 0.02$ :)

Repentant answered 13/7, 2009 at 14:45 Comment(0)
H
4

You could use a messaging service like ActiveMQ. It has both Python and Java support. This way, you can leave the complicated JNI or C bindings as they are and deal solely with what I consider a simple interface. Moreover, when the library gets updated, you don't need to change much, if anything.

Heddie answered 13/7, 2009 at 14:24 Comment(0)
R
3

Have you considered running Jython on the Java VM?

Rockhampton answered 13/7, 2009 at 14:16 Comment(3)
IronPython is for .NET, not Java. IKVM could unite the three potentially, but ick :)Daukas
Have I missed a reference to IronPython elsewhere ?Farro
Yes - in Cletus's answer before he edited it. (The edit doesn't show because it was within the first few minutes.)Daukas
O
3

I've investigated a similar setup with JNI. Maybe this will help if haven't seen it yet:

http://wiki.cacr.caltech.edu/danse/index.php/Communication_between_Java_and_Python

http://jpe.sourceforge.net/

Orose answered 13/7, 2009 at 14:21 Comment(0)
E
3

These are some of the tools which make it easier to bridge the gap between Python and Java:

1.Jython Python implemented in Java

2.JPype Allows Python to run java commands

3.Jepp Java embedded Python

4.JCC a C++ code generator for calling Java from C++/Python

5.Javabridge a package for running and interacting with the JVM from CPython

6.py4j Allows Python to run java commands.

7.voc Part of BeeWare suite. Converts python code to Java bytecode.

8.p2j Converts Python code to Java. No longer developed.

Expulsion answered 13/5, 2020 at 7:46 Comment(2)
I have updated the alternatives guide for JPype with this information.Regional
There is also GraalPythonJungjungfrau
H
2

If you can get your Python code to work in Jython, then you should be able to use that to call it from Java:

Housefather answered 13/7, 2009 at 14:17 Comment(0)
B
0

I also think that run command line in the Java wouldn't by bad practice (stackoverflow question here). Potentially share the data through some database.

I like the way to connect two apps via the bash pipe, but I have not practice in this, so I'm wondering how difficult is to write logic to handle this on both python/java sides.

Or other productive way could be to use the Remote Procedure Call (RPC) which supports procedural programming. Using RPC you can invokes methods in shared environments. As an example you can call a function in a remote machine from the local computer using RPC. We can define RPC as a communication type in distributed systems. (mentioned above by Marcin)

Or, very naive way would to be to communicate by the common file. But for sake of simplicity and speed, my vote is to use the shared database x rest API x socket communication.

Also I like the XML RPC as Marcin wrote.

I would like to recommend to avoid any complication to run Python under JVM or C++ binding. Better to use today trends which are obviously web technologies.

As a shared database the MongoDB may be good solution or even better the Redis as in memory database.

Bhakti answered 1/1, 2022 at 6:47 Comment(0)
E
0

Use pipes to communicate with python(a python script calls python library) via subprocesses, the whole process is like java<-> Pipes <-> py.

If JNI, you should be familiar with python's bindings(not recommended) and compiled files like *.so to work with java. The whole process is like py -> c -> .so/.pyd -> JNI -> jar.

Here is a good practice of stdio. https://github.com/JULIELab/java-stdio-ipc

Eyelid answered 23/11, 2022 at 7:50 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.