
Beginning Python (2005)
.pdf
Integrating Java with Python
testing provides the advantages of scripting without shipping the scripting packages in your application or using the scripting packages in production.
In addition to unit testing, scripting works well for full system testing. A system-testing package called the Grinder uses Jython to create test scripts. See http://grinder.sourceforge.net/ for more on the Grinder.
You can create one-off scripts for tasks such as data migration. If you just need to update a particular row in a database table, or fix a particular setting, you can do this a lot quicker using a script.
You can extend enterprise applications without having to redeploy the application. This is very handy if you need to keep your system running all the time. In addition, developers can extend the functionality of the system without requiring the security permissions to redeploy the application.
Jython, being based on the very popular Python language, enables you to do all of this, and more.
Comparing Python Implementations
The traditional Python implementation, often called C-Python, compiles and runs on a huge number of platforms, including Windows, Linux, and Mac OS X. C-Python is written in the C programming language. The Java-based Jython compiles and runs on any platform that supports the Java virtual machine (technically, any platform that supports J2SE, or Java 2 Standard Edition). This includes Windows, Linux, and Mac OS X. In this respect, the two Python implementations are very similar in how cross-platform they are.
However, Jython isn’t up to date compared to the traditional C-Python implementation. The C-Python implementation sports new features that have not yet been written in the Java implementation. That’s understandable, as the C-Python is where the first development happens, and the Jython developers have to re-implement every Python feature in Java.
Which foundation you use for Python scripting, C-Python or Jython, doesn’t really matter, because both support the Python language. In general, you’ll want to use C-Python unless you have a specific need to work within the Java platform. In that case, obviously, use Jython!
The rest of this chapter shows you how to do just that.
Installing Jython
As an open-source project, Jython doesn’t follow a set release cycle. Your best bet is to download the latest release from www.jython.org. Then, follow the instructions on the web site for installing Jython.
Older versions of Jython, such as 2.1, are packaged as a Java .class file of the installation program. When you run the file, the program will install Jython on your hard disk. Newer pre-release versions come packaged as a Zip file. Unzip the file to install Jython.
541
TEAM LinG

Chapter 22
After installing Jython, you should have two executable scripts in the Jython installation directory: jython and jythonc, similar in purpose to python and pythonc. The jythonc script, though, is intended to compile Python code into Java .class files. You need to have the jython script in your path, or available so you can call it.
On Windows, you will get DOS batch files jython.bat and jythonc.bat.
Running Jython
The jython script runs the Jython interpreter. The jythonc script runs the Jython compiler, which compiles Jython code to Java .class files. In most cases, you’ll want to use the jython script to run Jython.
Running Jython Interactively
Like Python with the python command, Jython supports an interactive mode. In this mode, you can enter Jython expressions, as you’d expect. Jython expressions are for the most part the same as Python expressions, except you can call upon the Java integration as well.
To run the Jython interpreter, run the jython script (jython.bat on Windows).
Try It Out |
Running the Jython Interpreter |
Run the interpreter and then enter in the following expressions:
$ ./jython
Jython 2.1 on java1.4.2_05 (JIT: null)
Type “copyright”, “credits” or “license” for more information.
>>>44 / 11
4
>>>324 / 101
3
>>>324.0 / 101.0
3.207920792079208
>>>324.0 / 101
3.207920792079208
>>>import sys
>>>sys.executable
>>>sys.platform ‘java1.4.2_05’
>>>sys.version_info (2, 1, 0, ‘final’, 0)
How It Works
As shown in this example, the Jython interpreter appears and acts like the Python interpreter. This is just what you’d expect, as Jython is supposed to be an implementation of the Python language on top of the Java platform.
542 |
TEAM LinG |

Integrating Java with Python
Math operations should work mostly the same as with Python. (“Mostly the same” means that some floating-point operations will create slightly different results.)
With the sys module, note how the property sys.executable is not set when you run Jython interactively. Also note that this example is using Jython 2.1.
On the same platform, you can see the differences when you run the same expressions with the python command, the C-Python interpreter. For example:
$ python
Python 2.3 (#1, Sep 13 2003, 00:49:11)
[GCC 3.3 20030304 (Apple Computer, Inc. build 1495)] on darwin
Type “help”, “copyright”, “credits” or “license” for more information.
>>>44 / 11
4
>>>324 / 101
3
>>>324.0 /101.0
3.2079207920792081
>>>324.0 / 101
3.2079207920792081
>>>import sys
>>>sys.executable
‘/usr/bin/python’
>>>sys.platform
‘darwin’
>>>sys.version_info (2, 3, 0, ‘final’, 0)
Note how the floating-point numbers show an extra digit by default. This example was run under Python 2.3 on Mac OS X 10.3, but the results should appear the same on Python 2.4 as well.
Running Jython Scripts
As with the python command, jython can also run your scripts, as shown in the following example.
Try It Out |
Running a Python Script |
Enter the following simple script and name the file jysys.py:
import sys
print ‘Python sys.path:’ print sys.path
print ‘Script arguments are:’ print sys.argv
543
TEAM LinG

Chapter 22
When you run this script with jython, you should see output like the following:
$ jython jysys.py 1 2 3 4 Python sys.path:
[‘’, ‘/Users/ericfj/writing/python/.’,
‘/Users/ericfj/Documents/java/jython-2.1/Lib’] Script arguments are:
[‘jysys.py’, ‘1’, ‘2’, ‘3’, ‘4’]
The filepaths will differ depending on where you installed Jython.
How It Works
In this example, you can pass any command-line arguments to the script. The 1 2 3 4 shown here just helps to see the arguments held in the sys.argv property.
The sys.path property holds a very small number of directories, especially when compared to the standard C-Python distribution. For example, you can run the same script with the python interpreter as shown here:
$ python jysys.py 1 2 3 4 Python sys.path: [‘/Users/ericfj/writing/python’,
‘/System/Library/Frameworks/Python.framework/Versions/2.3/lib/python23.zip’,
‘/System/Library/Frameworks/Python.framework/Versions/2.3/lib/python2.3’,
‘/System/Library/Frameworks/Python.framework/Versions/2.3/lib/python2.3/ plat-darwin’, ‘/System/Library/Frameworks/Python.framework/Versions/2.3/lib/python2.3/plat-mac’, ‘/System/Library/Frameworks/Python.framework/Versions/2.3/lib/python2.3/ plat-mac/lib-scriptpackages’, ‘/System/Library/Frameworks/Python.framework/Versions/2.3/lib/python2.3/lib-tk’, ‘/System/Library/Frameworks/Python.framework/Versions/2.3/lib/python2.3/ lib-dynload’, ‘/System/Library/Frameworks/Python.framework/Versions/2.3/lib/python2.3/ site-packages’]
Script arguments are: [‘jysys.py’, ‘1’, ‘2’, ‘3’, ‘4’]
In this case, note the larger number of directories in the sys.path property.
These examples were run on Mac OS X version 10.3.8. The paths will differ on other operating systems.
You’ll notice that the startup time for jython-run scripts is a lot longer than that for python-run scripts. That’s because of the longer time required to start the java command and load the entire Java environment.
Controlling the jython Script
The jython script itself merely acts as a simple wrapper over the java command. The jython script sets up the Java classpath and the python.home property. You can also pass arguments to the jython
544 |
TEAM LinG |

Integrating Java with Python
script to control how Jython runs, as well as arguments to your own scripts. The basic format of the jython command line follows:
jython jython_arguments what_to_run arguments_for_your_script
The jython_arguments can be -S to not imply an import site when Jython starts and -i to run Jython in interactive mode. You can also pass Java system properties, which will be passed in turn to your Jython scripts. The format for this is -Dproperty=value, which is a standard Java format for passing property settings on the command line.
You’ll normally pass the name of a Jython script file as the what_to_run section of the command — for example, the jysys.py script used in the previous example. The jython script offers more options, though, as shown in the following table.
Option |
Specifies |
|
|
filename.py |
Runs the given Jython script file |
-c command |
Runs the command string passed on the command line |
-jar jarfile |
Runs the Jython script __run__.py in the given jar file |
- |
Reads the commands to run from stdin. This allows you to pipe Jython com- |
|
mands to the Jython interpreter |
|
|
You can choose any one of the methods listed in the table.
In addition, the arguments_for_your_script are whatever arguments you want to pass to your script. These will be set into sys.argv[1:] as you’d expect.
Making Executable Commands
Note that because jython is a script, you cannot use the traditional shebang comment line to run Jython scripts. (On Unix and Linux systems, that’s the line that starts with the hash, or sharp, symbol and then has the exclamation point, or “bang,” so you get “sh(arp)-bang.” This tells the system that this command is how the program you’re running should be invoked.) For example, with a Python script, you can add the following line as the first line of your script:
#! /usr/bin/python
If your script has this line as the first line, and if the script is marked with execute permissions, the operating system can run your Python scripts as commands.
Note that Windows is the lone exception. Windows uses a different means to associate files ending in
.py with the Python interpreter.
With Jython scripts, though, you cannot use this mechanism. That’s because many operating systems require that the program that runs a script be a binary executable program, not a script itself. That is, you have a script you wrote that you want run by the jython script.
545
TEAM LinG

Chapter 22
To get around this problem, use the env command. For example, change the shebang line to the following:
#! /usr/bin/env jython
For this line to work, the jython script must be in your path.
Try It Out |
Making an Executable Script |
Insert the following lines into the previous jysys.py script. The new line is marked in bold.
#! /usr/bin/env jython
import sys
print ‘Python sys.path:’ print sys.path
print ‘Script arguments are:’ print sys.argv
Save this new file under the name jysys, with no extension. Use the chmod command to add execute permissions, as shown in the following example:
$ chmod a+x jysys
You can then run this new command:
$ ./jysys 1 2 3 4 Python sys.path:
[‘.’, ‘/Users/ericfj/writing/python/.’, ‘/Users/ericfj/Documents/java/jython-
2.1/Lib’]
Script arguments are: [‘./jysys’, ‘1’, ‘2’, ‘3’, ‘4’]
How It Works
The shebang comment works the same for Jython as it does for all other scripting languages. The only quirk with Jython is that the jython command itself is a script that calls the java command.
In the next section, you’ll learn more about how the java command runs Jython scripts.
Running Jython on Your Own
You don’t have to use the jython script, though, to execute Jython scripts. You can call the Jython interpreter just like any other Java application.
546 |
TEAM LinG |

Integrating Java with Python
The jython script itself is fairly short. Most of the action occurs by calling the java command with a large set of arguments, split up here for clarity:
java -Dpython.home=”/Users/ericfj/Documents/java/jython-2.1” \
-classpath “/Users/ericfj/Documents/java/jython-2.1/jython.jar:$CLASSPATH” \ “org.python.util.jython” “$@”
The paths will differ depending on where you installed Jython. The jython script, though, does nothing more than run the class org.python.util.jython from the jar file jython.jar (which the script adds to the Java classpath). The script also sets the python.home system property, necessary for Jython to find support files.
To run Jython on your own, you just need to ensure that jython.jar is in the classpath. Execute an interpreter class, such as org.python.util.jython. In addition, you need to set the python.home system property.
You also need to ensure that Jython is properly installed on every system that will run your Jython scripts.
Packaging Jython-Based Applications
Jython isn’t a standalone system. It requires a large number of Python scripts that form the Jython library. Thus, you need to include the jython.jar file as well as the Jython library files. At a bare minimum, you need the Lib and cachedir directories that come with the Jython distribution.
Jython needs to be able to write to the cachedir directory.
Java applications, especially J2EE enterprise applications, usually don’t require a set of files stored in a known location on the file system. If you include Jython, though, you’ll need to package the files, too.
Up to now, you can see that Jython really is Python, albeit an older version of Python. The real advantage of Jython, though, lies in the capability to integrate Python with Java, offering you the best of both worlds.
Integrating Java and Jython
The advantage of Jython comes into play when you integrate the Jython interpreter into your Java applications. With this combination, you can get the best of both the scripting world and the rich set of Java APIs. Jython enables you to instantiate objects from Java classes and treat these objects as Python objects. You can even extend Java classes within Jython scripts.
Jython actively tries to map Java data types to Python types and vice versa. This mapping isn’t always complete because the feature is under active development. For the most part, however, you’ll find that Jython does the right thing when converting to and from Python types.
547
TEAM LinG

Chapter 22
Using Java Classes in Jython
In general, treat Java classes as Python classes in your scripts. Jython uses the Python syntax for importing Java classes. Just think of Java packages as a combination of Python modules and classes. For example, to import java.util.Map into a Jython script, use the following code:
from java.util import Map
Note how this looks just like a Python import. You can try this out in your own scripts, as shown in the following example.
Try It Out |
Calling on Java Classes |
Enter the following script and name the file jystring.py:
import sys
from java.lang import StringBuffer, System
sb = StringBuffer(100) |
# Preallocate StringBuffer size for performance. |
|
sb.append(‘The platform |
is: ‘) |
|
sb.append(sys.platform) |
# Python property |
|
sb.append(‘ time for an |
omelette.’) |
|
sb.append(‘\n’) |
# Newline |
|
sb.append(‘Home directory: ‘) |
||
sb.append( System.getProperty(‘user.home’) ) |
||
sb.append(‘\n’) |
# Newline |
sb.append(‘Some numbers: ‘)
sb.append(44.1) sb.append(‘, ‘) sb.append(42) sb.append(‘ ‘)
# Try appending a tuple.
tup=( ‘Red’, ‘Green’, ‘Blue’, 255, 204, 127 ) sb.append(tup)
print sb.toString()
# Treat java.util.Properties as Python dictionary. props = System.getProperties()
print ‘User home directory:’, props[‘user.home’]
548 |
TEAM LinG |

Integrating Java with Python
When you run this script, you should see the following output:
$ jython jystring.py
The platform is: java1.4.2_05 time for an omelette. Home directory: /Users/ericfj
Some numbers: 44.1, 42 (‘Red’, ‘Green’, ‘Blue’, 255, 204, 127) User home directory: /Users/ericfj
Note that your output will depend on where your home directory is located and which version of Java you have installed.
How It Works
This script imports the Java StringBuffer class and then calls a specific constructor for the class:
from java.lang import StringBuffer
sb = StringBuffer(100)
The Jython interpreter converts the value 100 from a Python number to a Java number.
In Java programs, you do not need to import classes from the java.lang package. In Jython, import every Java class you use.
You can pass literal text strings as well as Python properties to the StringBuffer append method:
sb.append(‘The platform is: ‘)
sb.append(sys.platform) # Python property
This example shows that Jython will correctly convert Python properties into Java strings for use in a Java object. You can also pass the data returned by a Java method:
sb.append( System.getProperty(‘user.home’) )
In this case, the System.getProperty method returns an object of the Java type Object. Again, Jython properly handles this case, as Jython does with numbers:
sb.append(44.1)
sb.append(42)
You can even append a Python tuple:
tup=( ‘Red’, ‘Green’, ‘Blue’, 255, 204, 127 )
sb.append(tup)
The preceding example shows that Jython does the right thing when converting the tuple to a Java text string.
549
TEAM LinG

Chapter 22
In addition to converting Python types to Java types, Jython works the other way as well. You can pass a Java String object, returned by the toString method, to the Python print function:
print sb.toString()
This shows how you can treat Java strings as Python strings. You can also treat Java hash maps and hash tables as Python dictionaries, as shown in the following example:
props = System.getProperties()
print ‘User home directory:’, props[‘user.home’]
The Java System.getProperties method returns an object of type java.util.Properties, which Jython automatically converts into a Python dictionary.
Data type conversions as shown by this example are just what you’d expect when you integrate Java and Python. Jython does a lot of work under the covers, though. Java has a class hierarchy, as does Python. A large part of Jython is an attempt to merge these two large hierarchies together. Ultimately, you tend to get the best of both worlds.
For example, Python has the ability to pass named properties to a constructor. This proves especially useful when you work with APIs such as Swing for user interfaces. The Swing API has many, many classes. Each class supports a large number of properties on objects. Working with Java alone, you can only call the constructors that have been defined, and the parameters must be placed in a particular order. With Python, though, you can pass named properties to the object’s constructor and set as many properties as needed within one call.
The following example shows this technique.
Try It Out |
Creating a User Interface from Jython |
Enter the following script and name the file jyswing.py:
from java.lang import System
from javax.swing import JFrame, JButton, JLabel from java.awt import BorderLayout
#Exit application def exitApp(event):
System.exit(0)
#Use a tuple for size
frame = JFrame(size=(500,100))
# Use a tuple for RGB color values. frame.background = 127,255,127
button = JButton(label=’Push to Exit’, actionPerformed=exitApp) label = JLabel(text=’A Pythonic Swing Application’,
550 |
TEAM LinG |