I have seen in answered here that if you want to call a python script from java, you can use jython as a option.
But have seen other answers as well saying, you can use Process or ProcessBuilder and call their exec or start methods to run the python script.
As I understand jython allows you to program python in you java code, but it allows you to call python scripts as well via, PythonInterpreter.execfile.
So I'm wondering what are my options if I want to call a python script (e.g. text processing script which uses nltk) from my java code and along with some arguments and return the results back to my java programme? which option should I use?
Jython is an implementation of the Python language for the Java platform
(source)
You can simply use ProcessBuilder if there is a regular python script on a machine that has regular python installed. This saves you from having to include a whole python runtime in your java application. You can pass parameters quite easily, the returned text is a little trickier: See http://examples.javacodegeeks.com/core-java/lang/processbuilder/java-lang-processbuilder-example/ or other examples. Basically anything that the python program prints can be captured that way.
However if you don't like external dependencies and prefer shipping everything in a single application you can try jython. It has some limitations though since it doesn't come with all those modules and it seems it may have difficulties with C modules. Getting Python's nltk.wordnet module working for Jython looks like an explanation on how to get nltk to run with it. Arguments and return values should be simpler with jython since the integration is better. And if you want more than just printed text, Jython can even call into java code directly from python. That would give you interesting options for hybrid code.
**Sorry, I am very new to both python and java so I might not recognize that this has been answered and only needs adjusted for my situation.
Essentially I have a script manager that operates in a python environment and I need to pass data off to the bonej plugin for analysis, which should then return an array that will then be used by another python script for further analysis.
I have been directed to jython as a way to do this, but I can't figure out how to import imageJ as if it were a module.
I know that I can simply open imagej from a command line and direct it to analyze an image, but this is not what I need because it simply returns an average in a segment of bone.
Basically I need to tell imagej that it should analyze this segment of bone, return the array, then this next segment of bone. An additional python script interpolates the arrays onto a predefined background grid.
If anyone has some insight on how to achieve this back and fort from jython I would appreciate it.
You can indeed use Jython to call ImageJ. See the Jython scripting page on the Fiji wiki for an overview and lots of example code. One easy way to get started from within ImageJ is to use the Script Editor. You can then invoke your Jython scripts from the command line using the ImageJ launcher [instructions]. Or you can run them via the jython executable by adding the needed Java libraries to the classpath.
But beware: this does not provide total integration between Python libraries and Java ones. The problem is that many Python libraries are backed by C code, making them accessible only from CPython, and not from Jython. For example, the very popular SciPy and NumPy libraries cannot be called directly from Jython code.
How to Launch REPL using java Swing application. As shown in Image. This REPL should be able to run all functions provided by Clojure Build-in libraray and other developed libraries by user. (provied as jar in classpath).
Point is, how to run Java clojure.jar clojure.main from swing so that it will show user defined Namespace. like myRepl=>
I'm not sure I understand your question exactly. Do you want to write such REPL or to just use it?
In any case, googling for "clojure swing repl" seems to show interesting results, one of which is: https://github.com/alandipert/clj-swingrepl
N.B. I haven't tested this.
I have several scripts written in perl, python, and java (wrapped under java GUI with system calls to perl & python). And I have many not-tech-savy users that need to use this in their windows machines (xp & 7).
To avoid users from installing perl,python,and java and to avoid potential incompatibility between various versions of these interpreters, I'd like to make a local copy of these interpreters in a folder and then calling them. I'd zip the whole folder (which would also contain my code) and send it away.
I'd have to worry about environment variables and make calls to the correct interpreter (especially when other versions of python,java,perl may exists in their current system), but not sure what other problems I may face. Any better ideas?
I never used jython and do not know the overhead of moving to it. I also suspect a complex python system, with many files and 3rd party modules will have problems. Same with perl scripts and I don't know a robust perl interpreter callable from java.
Thank you, in advance.
Try Portable Python and Portable Perl. You can unzip them into your application tree and they should work.
Why don't you try migrating your perl/python code into java and then packagin everything into a nice webstart application? What do perl/python offer that java doesn't support?
For perl you can use something like perl2exe and for python py2exe so you can have 2 exes (which would include all the necessary interpreter bits) and invoke them as resources from within java? Or unzip them inside user's home directory and call them again as normal external programs (ProcessBuilder ?) ?
What is the best way to call java from python?
(jython and RPC are not an option for me).
I've heard of JCC: http://pypi.python.org/pypi/JCC/1.9
a C++ code generator for calling Java from C++/Python
But this requires compiling every possible call; I would prefer another solution.
I've hear about JPype: http://jpype.sourceforge.net/
tutorial: http://www.slideshare.net/onyame/mixing-python-and-java
import jpype
jpype.startJVM(path to jvm.dll, "-ea")
javaPackage = jpype.JPackage("JavaPackageName")
javaClass = javaPackage.JavaClassName
javaObject = javaClass()
javaObject.JavaMethodName()
jpype.shutdownJVM()
This looks like what I need.
However, the last release is from Jan 2009 and I see people failing to compile JPype.
Is JPype a dead project?
Are there any other alternatives?
You could also use Py4J. There is an example on the frontpage and lots of documentation, but essentially, you just call Java methods from your python code as if they were python methods:
from py4j.java_gateway import JavaGateway
gateway = JavaGateway() # connect to the JVM
java_object = gateway.jvm.mypackage.MyClass() # invoke constructor
other_object = java_object.doThat()
other_object.doThis(1,'abc')
gateway.jvm.java.lang.System.out.println('Hello World!') # call a static method
As opposed to Jython, one part of Py4J runs in the Python VM so it is always "up to date" with the latest version of Python and you can use libraries that do not run well on Jython (e.g., lxml). The other part runs in the Java VM you want to call.
The communication is done through sockets instead of JNI and Py4J has its own protocol (to optimize certain cases, to manage memory, etc.)
Disclaimer: I am the author of Py4J
Here is my summary of this problem: 5 Ways of Calling Java from Python
http://baojie.org/blog/2014/06/16/call-java-from-python/ (cached)
Short answer: Jpype works pretty well and is proven in many projects (such as python-boilerpipe), but Pyjnius is faster and simpler than JPype
I have tried Pyjnius/Jnius, JCC, javabridge, Jpype and Py4j.
Py4j is a bit hard to use, as you need to start a gateway, adding another layer of fragility.
Pyjnius docs and Github.
From the github page:
A Python module to access Java classes as Python classes using JNI.
PyJNIus is a "Work In Progress".
Quick overview
>>> from jnius import autoclass
>>> autoclass('java.lang.System').out.println('Hello world')
Hello world
>>> Stack = autoclass('java.util.Stack')
>>> stack = Stack()
>>> stack.push('hello')
>>> stack.push('world')
>>> print stack.pop()
world
>>> print stack.pop()
hello
If you're in Python 3, there's a fork of JPype called JPype1-py3
pip install JPype1-py3
This works for me on OSX / Python 3.4.3. (You may need to export JAVA_HOME=/Library/Java/JavaVirtualMachines/your-java-version)
from jpype import *
startJVM(getDefaultJVMPath(), "-ea")
java.lang.System.out.println("hello world")
shutdownJVM()
I'm on OSX 10.10.2, and succeeded in using JPype.
Ran into installation problems with Jnius (others have too), Javabridge installed but gave mysterious errors when I tried to use it, PyJ4 has this inconvenience of having to start a Gateway server in Java first, JCC wouldn't install. Finally, JPype ended up working. There's a maintained fork of JPype on Github. It has the major advantages that (a) it installs properly and (b) it can very efficiently convert java arrays to numpy array (np_arr = java_arr[:])
The installation process was:
git clone https://github.com/originell/jpype.git
cd jpype
python setup.py install
And you should be able to import jpype
The following demo worked:
import jpype as jp
jp.startJVM(jp.getDefaultJVMPath(), "-ea")
jp.java.lang.System.out.println("hello world")
jp.shutdownJVM()
When I tried calling my own java code, I had to first compile (javac ./blah/HelloWorldJPype.java), and I had to change the JVM path from the default (otherwise you'll get inexplicable "class not found" errors). For me, this meant changing the startJVM command to:
jp.startJVM('/Library/Java/JavaVirtualMachines/jdk1.7.0_79.jdk/Contents/MacOS/libjli.dylib', "-ea")
c = jp.JClass('blah.HelloWorldJPype')
# Where my java class file is in ./blah/HelloWorldJPype.class
...
I've been integrating a lot of stuff into Python lately, including Java. The most robust method I've found is to use IKVM and a C# wrapper.
IKVM has a neat little application that allows you to take any Java JAR, and convert it directly to .Net DLL. It simply translates the JVM bytecode to CLR bytecode. See http://sourceforge.net/p/ikvm/wiki/Ikvmc/ for details.
The converted library behaves just like a native C# library, and you can use it without needing the JVM. You can then create a C# DLL wrapper project, and add a reference to the converted DLL.
You can now create some wrapper stubs that call the methods that you want to expose, and mark those methods as DllEport. See https://stackoverflow.com/a/29854281/1977538 for details.
The wrapper DLL acts just like a native C library, with the exported methods looking just like exported C methods. You can connect to them using ctype as usual.
I've tried it with Python 2.7, but it should work with 3.0 as well. Works on Windows and the Linuxes
If you happen to use C#, then this is probably the best approach to try when integrating almost anything into python.
I'm just beginning to use JPype 0.5.4.2 (july 2011) and it looks like it's working nicely...
I'm on Xubuntu 10.04
I'm assuming that if you can get from C++ to Java then you are all set. I've seen a product of the kind you mention work well. As it happens the one we used was CodeMesh. I'm not specifically endorsing this vendor, or making any statement about their product's relative quality, but I have seen it work in quite a high volume scenario.
I would say generally that if at all possible I would recommend keeping away from direct integration via JNI if you can. Some simple REST service approach, or queue-based architecture will tend to be simpler to develop and diagnose. You can get quite decent perfomance if you use such decoupled technologies carefully.
Through my own experience trying to run some java code from within python in a manner similar to how python code runs within java code in python, I was unable to find a straightforward methodology.
My solution to my problem was by running this java code as BeanShell scripts by calling the BeanShell interpreter as a shell command from within my python code after editing the java code in a temporary file with the appropriate packages and variables.
If what I am talking about is helpful in any manner, I am glad to help you share more details of my solutions.