My project uses some packages that are available only in Python and heavily rely on C libraries. The project also greatly benefits from Java libraries and the JVM. What's the optimal way to call Python functions from Java?
I tried:
-
Small web-services: overhead to serialize data, start and stop the services. Also debugging is harder and implementing each new function is now double the effort.
-
Jpy: a library that runs an interpreter in the JVM. Spare the service start/stop, but: isn't really feasible for more than a single-liner, data translation between Java and Python is cumbersome, and I also encountered runtime segmentation fault errors.
Any other options?
The project is in the machine-learning domain, so involves exchanging large numeric arrays and text. In some cases the execution switches back and forth between the platforms.
Using Python from within Java - Stack Overflow
can both Java and Python be used at the same time on App Engine? - Stack Overflow
Best way to combine Python and Java?
How to merge two Queues?
Videos
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.
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:
- Create a SWIG interface for all method calls from Java to C++.
- Create C/C++ code that will receive your calls and internally call python interpreter with right params.
- 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.
I'm aware of the Jython project, but it looks like this represents a way to use Java and its libraries from within Python, rather than the other way round - am I wrong about this?
Yes, you are wrong. You can either call a command line interpreter to run python code using Jyton or use python code from Java. In the past there was also a python-to-Java compiler, but it got discontinued with Jython 2.2
I would write a Python module to handle the text and language processing, and then build a small bridge in jython that your java program can interact with. The jython bridge will be a very simple one, that's really only responsible for forwarding calls to the python module, and return the answer from the python module to the java module. Jython is really easy to use, and setup shouldn't take you more than 15 minutes.
Best of luck!
I had exactly the same need a week ago or so, and found a solution: Can Java and Python coexist in the same app?
EDIT: I accepted the first answer, but it happens that the second answer gave me best results, as i explain on the comments there.
EDIT 2: Well, it might not be exactly the same need, as i only needed to access the same datastore. If you want Java and Python running side-by-side, then i think Jython would be the best solution, as larsmans mentioned above.
Use py4j to communicate java and python and you need only secret id or user id to connect with google app engine .But if you need standalone application for both then you will need yaml file and their configuration.
from py4j.java_gateway import JavaGateway
gateway = JavaGateway() # connect to the JVM
gateway.jvm.java.lang.System.out.println('Hello World!')
Alternatively you can use google app engine plugin for eclipse (if you are using) and deploy java project using run->run as-> Google Web Application and integrate python using Jython. https://developers.google.com/eclipse/docs/creating_new_webapp?hl=en