Jython & Java:
the whole is greater than the sum of the parts
Jython is a Java Virtual Machine (JVM) implementation of Python.
Python is a high level, general purpose programming language.
It supports list processing, regular expressions, multi-threading,
complex numbers and a host of other advanced features in a late binding,
multiple-inheritance object-oriented environment.
It can run interpreted or be compiled.
It can run stand-alone, call C programs, or be called from C.
Python's clean and simple
syntax make it easy to read, easy to learn, and is often used for
beginning programming classes.
At the same time, Python is robust, fully featured, and frequently
the language of choice for graduate computer science courses.
Python's closest cousin is Ruby; Perl and Tcl have similarities.
Jython is a 100% Java implementation making it portable
to wherever JVMs are found.
Jython can subclass and instantiate Java classes, and Jython classes can
be accessed from Java programs.
In addition, Java can easily invoke the Jython interpreter
to run other source codes at run time.
Java compiled byte codes comply with
all the Java security mechanisms making for secure client-side applets
written in Python.
What follows are brief introductions on how to install Jython, call Java
classes, and access Jython codes from Java.
You will also find an annotated list of additional references.
Contents:
Jython Installation
Call Java classes from Jython programs
Call Jython classes from Java
Run Python code from Java
Appendix A: RunPython.java
Appendix B: Jython References
Jython Installation
These instructions are specific to Windows 95/98/NT platforms and assume
Java v1.2 or later is already installed (Java's java.exe
and rt.jar files are findable via the PATH and CLASSPATH
variables respectively).
*nix users should adapt appropriately.
The Jython installer is a Java .class file. The latest installer is
"jython-21.class" and can be downloaded from the
Jython web site. Install Jython by typing
java jython-21
An installer window will ask where Jython is to be installed.
Any location is acceptable, but C:\Jython21 is a good choice.
Upon completion, be sure you have C:\Jython21 in your PATH
and CLASSPATH environment variables so Jython.bat, Jythonc.bat
and jython.jar are visible.
Windows 9x users may want to modify
autoexec.bat to look something like the following.
SET WINPATH=C:\windows;C:\windows\command
SET JAVAPATH=C:\jdk1.4.0\bin
SET JythonPATH=C:\Jython21;C:\Jython21\Lib
SET PATH=.;%JAVAPATH%;%JythonPATH%;C:\Python;%WINPATH%
SET JAVACLASSPATH=C:\jdk1.4.0\jre\lib
SET JythonCLASSPATH=C:\Jython21
SET CLASSPATH=.;%JAVACLASSPATH%;%JythonCLASSPATH%
(Putting a copy of jython.jar in the same directory as rt.jar
avoids the CLASSPATH issue.)
How to call Java classes from Jython programs
The most common use of Jython is the quick access of Java classes in
a RAD or prototyping environment.
Here is a very simple example using both Python (os.getcwd)
and Java Swing (JFileChooser) library calls.
# file: simpleJy.py
from javax.swing import JFileChooser
from java.io import File
import os, sys
def chooseFile(cwd=''):
chooser = JFileChooser()
chooser.setCurrentDirectory(File(cwd))
returnVal = chooser.showOpenDialog(None)
if returnVal == JFileChooser.APPROVE_OPTION:
return chooser.getSelectedFile().getPath() # or perhaps .getName()
return ''
if __name__ == '__main__':
filepath = chooseFile(os.getcwd())
if filepath:
print filepath
else:
print '<< no file selected >>'
sys.exit()
Run this code from a command line by typing
jython simpleJy.py
How to create Jython classes callable from Java programs
A Jython class is a Python class with the restriction that it
be single inheritance and the doc string be a Java signature.
Only those classes to be called from Java are so affected; all of the
remaining Jython code is unchanged.
Write and test as much of your program as possible as a pure Python
program.
This is optional, but it is usually quicker than launching
the JVM each time you want to run a test.
Then modify and test your Python code as a Jython class.
This should not be difficult, but here are a few things to note.
-
Be sure you import java, and as necessary, javax and other packages.
import java
import javax
-
The Jython class must inherit from a Java class. It may be
java.lang.Object, or another if you wish to inherit behavior.
It is best if you use fully qualified Java class names.
class MyFrame(javax.swing.JFrame): or...
class MyFrame(JFrame):
-
For those methods to be called from Java, there must be a Java signature
so the Java compiler can know the proper data types.
Recall that Python allows a properly indented string to be a comment, or
more properly, documentation, if it is the first statement in a method
declaration.
Jython uses this string to be the Java signature if it begins with
@sig. In the following example there is only one
argument, a Java string, and no return value.
Note the string begins with @sig and String has a fully
qualified name.
def doit(filename):
"@sig public void
doit(java.lang.String filename)"
...
In this example there is a return argument, a Java Integer.
def doit(filename):
"@sig public java.lang.Integer
doit(java.lang.String filename)"
...
return someIntegerValue
-
The .py files should be clean of test code.
Either comment out your test code or put the test code in a
separate file that you will not submit to the Jython compiler.
-
Only the core Python libraries were ported to Jython and subsequently
compiled into the jython.jar file.
Numerous other Python libraries are usable but you will have to first
compile them to .class files.
(See the the Python documentation for a list of core and non-core
modules.)
Compile the Jython code with jythonc from a command line.
This may take a few seconds.
Typing jythonc --help will show you how to define packages
and build .jar files.
(Yes, --help is not a valid switch, but it does trigger the usage
output.)
If you use jythonc with no options, you will find your .class
files in the jpywork subdir.
For example, if your module name is Sample and you type
jythonc Sample
you should find Sample.java, Sample.class, and
Sample$_PyInner.class in jpywork.
Move those .class files to somewhere in your CLASSPATH.
A Java program calling your new Jython classes might contain lines
like...
// file: TestSample
import Sample;
...
Sample samp = new Sample();
samp.doit("test.txt");
...
If you are using an IDE, be sure to include rt.jar,
jython.jar and the jpywork .class files in your project.
How to compile additional Python library modules
Go to your Python /lib directory and copy the .py files of interest
to a working directory.
Compile each with jythonc and you should find the .class
files in the jpywork subdirectory.
Move the .class files to your CLASSPATH or combine them into a .jar
and move that to your CLASSPATH.
NB: Python only modules can receive this treatment; modules calling
compiled C/C++ code will not work.
How to run Python programs from Java
An easy way to run Python programs from within Java is to invoke
the Jython interpreter to run the Python code.
The Python programs require little or no modification.
Unlike all Java code which must be in OO methods, there is no such requirement
for Python. Procedural Python is fine.
Start by writing and testing your Python program as a Python program.
Then include code, like that shown below, in your Java code. It's quicker
that way.
In following example, main instantiates a Jython interpreter,
loads a value into num, runs sq.py, and extracts and prints
the answer.
(Here everything runs in main, but that is not necessary.)
// file RunSqPy.java
import org.python.util.PythonInterpreter;
import org.python.core.*;
public class RunSqPy {
static public void main(String[] args) throws PyException {
// instantiate the interpreter
PythonInterpreter interp = new PythonInterpreter();
// set runtime args as Jython global variables
interp.set("num", new PyInteger(2));
// cause the Python program to be run (a fully
// qualified pathname is allowed)
interp.execfile("sq.py");
// get values
PyObject sq = interp.get("square");
PyObject num = interp.get("num");
// ...and do with them as you please (you may need
// to cast them depending on usage)
System.out.println("square of " + num + " is " + sq);
}
}
Compile this with javac RunSqPy.java, but before running it, be
sure you have the file sq.py as shown below.
# file: sq.py
# this could be a whole lot more sophisticated, but
# this is sufficient to illustrate how to access
# variables before and after execution.
print '--- sq.py start ---'
if __name__ == '__main__':
num = 7
print 'num =', num
square = num**2
print 'square =', square
print '---- sq.py end ----'
Typing java RunSqPy should yield
--- sq.py start ---
num = 2
square = 4
---- sq.py end ----
square of 2 is 4
but typing python sq.py should give
--- sq.py start ---
num = 7
square = 49
---- sq.py end ----
Remember, only the core Python libraries were ported to Jython.
You will have to make available any other Python modules you need.
Compiling the Java code in Appendix A
(RunPython.java) provides a general purpose Java class to
facilitate the running of Python code.
This cleaner example does the same as RunSqPy.java above.
// file: ShortTestPython.java
import RunPython.*;
public class ShortTestPython {
public static void main(String[] args) {
RunPython py = new RunPython();
py.setInt("num", 2);
py.run("sq.py");
System.out.println("square = " + py.getInt("square"));
}
}
Your Python program might want to have logic that can determine if it is
running standalone (from a command line) or is being called from a Java
program.
A simple declarative technique is
if __name__ == '__main__':
num = 7
If your code needs to run in multiple environments where the value of
a variable can be set set in one of several ways, you will need some way
of detecting whether it has already been set or not. The following
example allows you to not give a value if the variable already
has one.
try: # if not already defined (fm Java), an
junk = num # exception will be thrown
except:
num = 7 # set a default value or inspect the
# command line arguments (sys.argv)
Appendix A: RunPython.java
The use of this Java class, RunPython, is strictly optional, but it
does simplifiy access to the Jython interpreter.
import org.python.util.PythonInterpreter;
import org.python.core.*;
public class RunPython {
// instantiate a fresh interpreter
PythonInterpreter interp = new PythonInterpreter();
// a 'do nothing' constructor
public RunPython() { }
// use this contructor if no variables to be passed
// in and you want to run a Jython program (saves a line)
public RunPython(String filename) {
run(filename);
}
// run the named Jython program
public void run(String filename){
interp.execfile(filename);
}
// gets an integer return value
public int getInt(String name) {
return ((PyInteger) interp.get(name)).getValue();
}
// sets an input integer value
public void setInt(String name, int value){
interp.set(name, new PyInteger(value));
}
// gets a double return value (Python floats are doubles)
public double getDouble(String name) {
return ((PyFloat) interp.get(name)).getValue();
}
// sets an input double value (Python floats are doubles)
public void setDouble(String name, double value){
interp.set(name, new PyFloat(value));
}
// gets a string return value
public String getStr(String name) {
return ((PyString) interp.get(name)).toString();
}
// sets an input string value
public void setStr(String name, String value){
interp.set(name, new PyString(value));
}
// can add more getters and setters for complex,
// list, dictionary, tuple, etc. ...someday.
}
Appendix B: Jython References
An excellent book devoted entirely to Jython is "Jython Essentials" by
Pedroni and Rappin, published by O'Reilly
(ISBN 0596002475).
Mark Lutz devoted a section to Jpython (Jython) in his book "Programming
Python", also published by O'Reilly
(ISBN 0596158106).
"The Quick Python Book" also has a section about Jpython. The 1st edition
was written by Harms and McDonald; the 2nd edition is by Ceder and Jones.
(ISBN 193518220X).
"The Definitive Guide to Jython" is a free, open source, Creative Commons
online book. It is also available in hard copy.
(ISBN 1430225270).
And, there is some good information at the
Jython web site.
|