How to Use JPype
March 31, 2008 by Isaac
Background
I love Python and my personal experience has shown that testers are about 4x more productive when using Python than when using Java. However, at work I am a tester on a Java application. I've been looking for a way to bridge that gap and allow me to write my tests in Python but test a Java application.
I've looked into Jython and while it had many advantages it has one major drawback that I can't live with: Jython only implements Python 2.2. Most of the time this is fine, but there are times where I use Python 2.4 or 2.5 features and don't want to create a workaround just so I can use an older Python standard. If I had the money I would pay someone to bring Jython up to date. But, that's not a possibility.
I did find another alternative that so far seems to work great. It is still in development, but JPype seems to be working fairly well. JPype differs in philosophy from Jython in a fundamental way: Jython is a complete reimplementation of Python in Java, whereas JPype is a bridge between CPython and native Java.
Kicking The Tires
This article is a "how to," so let's get down to business. I'm going to create a Java class that I would like to access from Python. Here is Java class:
package org.wg3i.test; class Test { private String msg; public Test() { } public void speak(String msg) { System.out.println(msg); } public void setString(String s) { msg = s; } public String getString() { return msg; } }
The class is simple enough, but it will illustrate the basic JPype usage. For my testing I compiled this and placed it into a jar file. Feel free to leave it as a class file if you wish. I'll show you how to deal with both situations below.
For reference, here is my ant build file:
<project name="TestProject" basedir="." default="jar"> <property name="src.dir" value="src"></property> <property name="build.dir" value="build"></property> <property name="classes.dir" value="${build.dir}/classes"></property> <property name="jar.dir" value="${build.dir}/jar"></property> <target name="clean"> <delete dir="build"> </delete> <target name="compile"> <mkdir dir="${classes.dir}"> <javac srcdir="${src.dir}" destdir="${classes.dir}"> </javac> <target name="jar" depends="compile"> <mkdir dir="${jar.dir}"> <jar destfile="${jar.dir}/${ant.project.name}.jar" basedir="${classes.dir}"> </jar> <target name="clean-build" depends="clean,jar"> </target> </mkdir></target></mkdir></target></target></project>
After creating a jar file you are ready to go. Here is the Python code to utilize a jar file and create an instance of the Java class.
# Simple little JPype test. Note: This test assumes # that the jar file is in the build/jar directory # relative to the current directory import jpype import os.path jarpath = os.path.join(os.path.abspath('.'), 'build/jar') jpype.startJVM(jpype.getDefaultJVMPath(), "-Djava.ext.dirs=%s" % jarpath) Test = jpype.JClass('org.wg3i.test.Test') # get the class t = Test() # create an instance of the class t.speak("This is a test message") # try to call one of the class methods t.setString("Hello, World") # set a string s = t.getString() # get the string back print s jpype.shutdownJVM()
In a nutshell that's it. I promised to show you how to initialize JPype when you have class files and not jar files. Here's a Python example that shows that This example also shows the use of the JPackage method, which gets a package, not a class.
import jpype import os.path classpath = os.path.join(os.path.abspath('.'), 'build/classes') jpype.startJVM(jpype.getDefaultJVMPath(), "-Djava.class.path=%s" % classpath) testPkg = jpype.JPackage('org').wg3i.test # get the package Test = testPkg.Test # get the class t = Test() # create an instance of the class t.speak("This is a test message") # try to call one of the class methods t.setString("Hello, World") # set a string s = t.getString() # get the string back print s jpype.shutdownJVM()
Conclusion
There are many things I have not covered, such as passing arrays back and forth, types other than strings, exceptions, etc. However, this should be enough to get you started using JPype. I'd be interested in hearing your own experiences or suggestions.
Posted in 
content rss
