
Beginning Python (2005)
.pdf
Integrating Java with Python
This command creates a WEB-INF directory. The name and case of this directory are very important. In J2EE, the WEB-INF directory contains the libraries and deployment information about your Web application:
$ mkdir webapps/jython/WEB-INF/lib
The lib subdirectory holds any jar files needed by your Web application. You need one jar file, jython. jar, from the Jython installation. Copy this file into the webapps/jython/WEB-INF/lib directory that you just created.
Next, you need to create a file named web.xml in the webapps/jython/WEB-INF directory. Enter the following text into web.xml:
<?xml version=”1.0” encoding=”ISO-8859-1”?> <web-app>
<servlet> <servlet-name>PyServlet</servlet-name>
<servlet-class>org.python.util.PyServlet</servlet-class> <init-param>
<param-name>python.home</param-name> <param-value>/Users/ericfj/Documents/java/jython-2.1</param-value>
</init-param> </servlet> <servlet-mapping>
<servlet-name>PyServlet</servlet-name> <url-pattern>*.py</url-pattern>
</servlet-mapping> </web-app>
Change the path in bold to the full path to the directory in which you installed Jython.
You should now have two files in your new Web application:
webapps/jython/WEB-INF/lib/jython.jar
webapps/jython/WEB-INF/web.xml
These two files are essential. Next, you need to create some Python scripts within the new Web application.
This chapter presents a whirlwind introduction to J2EE, a frightfully complicated subject. If you’re not familiar with J2EE, you can look up more information in a J2EE tutorial, such as the one located at http://java.sun.com/j2ee/1.4/docs/tutorial/doc/index.html.
Extending HttpServlet
The javax.servlet.http.HttpServlet class provides the main hook for J2EE developers to create servlets. J2EE developers extend HttpServlet with their own classes to create servlets. With the PyServlet class, you can do the same with Jython. With Jython, however, this task becomes a lot easier than writing everything in Java.
561
TEAM LinG

Chapter 22
Use the following code as a template for creating your servlet classes in Jython:
from javax.servlet.http import HttpServlet
class verify(HttpServlet):
def doGet(self, request, response): self.handleRequest(request, response)
def doPost(self, request, response): self.handleRequest(request, response)
def handleRequest(self, request, response): response.setContentType(“text/html”); out = response.getOutputStream()
print >>out, “YOUR OUTPUT HERE” out.close()
return
Your classes must inherit from HttpServlet. In addition, you need to create two methods, doGet and doPost, as described in the following table.
Method |
Usage |
|
|
DoGet |
Handles GET requests, which place all the parameters on the URL |
DoPost |
Handles POST requests, usually with data from a form |
|
|
In virtually all cases, you want both methods to perform the same task. Any differences in these methods only serve to make your Web applications harder to debug. Therefore, write another method that both can call, such as the handleRequest method shown in the previous template.
In your handleRequest method, you must perform a number of tasks. All must be correct, or you will see an error or no output. These tasks include the following:
Set the proper content type on the response object. In most cases, this will be text/html.
Get an output stream from the response object.
Write all output to this stream.
Close the stream.
The following example shows how to create a real servlet from this code template.
Try It Out |
Writing a Python Servlet |
Enter the following and save the file as webapps/jython/verify.py:
import sys
from javax.servlet.http import HttpServlet
class verify(HttpServlet):
562 |
TEAM LinG |

Integrating Java with Python
def doGet(self, request, response): self.handleRequest(request, response)
def doPost(self, request, response): self.handleRequest(request, response)
def handleRequest(self, request, response): response.setContentType(“text/html”);
out = response.getOutputStream()
print >>out, “<html><head><title>”
print >>out, “Jython Is Running</title></head>” print >>out, “<body>”
print >>out, “<h2>Jython is running</h2>” print >>out, “<p>”
print >>out, “Version:”, sys.version, “ verified.” print >>out, “</p>”
print >>out, “</body></html>” out.close()
return
You must place this file within your Web application in the webapps/jython directory. After saving the file, stop and then restart Tomcat to ensure that your changes are recognized.
Test your new servlet by entering the following URL in your Web browser: http://localhost:8080/ jython/verify.py. Figure 22-3 shows the results you should see.
Figure 22-3
How It Works
Three crucial parts make this servlet work:
Tomcat must be running.
You must have the correct directory structure and contents for your Web application.
The URL must name a Python script in your Web application. The script must have a .py filename extension.
563
TEAM LinG

Chapter 22
In the web.xml file created previously, you registered the servlet PyServlet for all files ending with a
.py extension. Thus, with a URL of http://localhost:8080/jython/verify.py, Tomcat will direct the servlet PyServlet to handle the request. The following table splits this URL into its important components.
Component |
Usage |
|
|
http:// |
Defines the protocol used, HTTP in this case |
jython |
This is the name of your Web application (it could be any name you wanted). |
|
With Tomcat, there must be a webapps/jython directory. |
verify.py |
Name of a file within the Web application. The .py extension signals that the |
|
PyServlet should handle the request. |
|
|
The actual servlet class itself is rather small and follows the code template shown previously. The main action of this servlet occurs in the handleRequest method:
def handleRequest(self, request, response): response.setContentType(“text/html”);
out = response.getOutputStream() print >>out, “<html><head><title>”
print >>out, “Jython Is Running</title></head>” print >>out, “<body>”
print >>out, “<h2>Jython is running</h2>” print >>out, “<p>”
print >>out, “Version:”, sys.version, “ verified.” print >>out, “</p>”
print >>out, “</body></html>” out.close()
return
Most of this method is a number of print statements, sending HTML-formatted text to the output stream. Compare this method for creating Web applications with the technologies introduced in Chapter 21.
As you can see, you really need to know both Python and Java, at least a bit, to be able to work with Jython. That’s why choosing the right tools is important.
Choosing Tools for Jython
Because Jython focuses on working with Java as well as Python, the best choice for Jython tools comes from the Java arena. The following tools can help with your Jython work:
The jEdit text editor (www.jedit.org/) includes a number of plugins for working with Python. The editor highlights Python syntax, whether you are working with Python or Jython. In addition, the JythonInterpreter plugin includes an embedded Jython interpreter. See http:// plugins.jedit.org/ for more on jEdit plugins.
564 |
TEAM LinG |

Integrating Java with Python
The Eclipse Integrated Development Environment, or IDE, provides excellent support for Java development. In addition, two Eclipse plugins stand out for Jython usage: PyDev, for working with Python, at http://sourceforge.net/projects/pydev/; and the RedRobin Jython development tools plugin, at http://home.tiscali.be/redrobin/jython/. The latter plugin focuses specifically on Jython. Download Eclipse itself from www.eclipse.org.
Whichever tools you choose, all you really need is a text editor and a command-line shell. Furthermore, the tools you choose can help with testing, especially testing Java applications.
Testing from Jython
Because Jython provides an interactive environment on top of the Java platform, Jython makes an excellent tool for interactive testing. The following examples show how you can use Jython’s interactive mode to explore your Java environment.
Try It Out |
Exploring Your Environment with Jython |
Enter the following commands to see information on the Java Map interface:
$ jython
Jython 2.1 on java1.4.2_05 (JIT: null)
Type “copyright”, “credits” or “license” for more information.
>>>from java.util import Map
>>>print dir(Map)
[‘clear’, ‘containsKey’, ‘containsValue’, ‘empty’, ‘entrySet’, ‘equals’, ‘get’, ‘hashCode’, ‘isEmpty’, ‘keySet’, ‘put’, ‘putAll’, ‘remove’, ‘size’, ‘values’]
>>>
How It Works
This example uses the Python dir function to display information about the java.util.Map interface in Java. You can list information on any Java class or interface.
As another example, you can examine the JNDI, or Java Naming and Directory Interface, classes such as
InitialContext, as shown here:
$ jython
Jython 2.1 on java1.4.2_05 (JIT: null)
Type “copyright”, “credits” or “license” for more information.
>>>from javax.naming import InitialContext
>>>print dir(InitialContext)
[‘bind’, ‘composeName’, ‘createSubcontext’, ‘destroySubcontext’, ‘getNameParser’, ‘list’, ‘listBindings’, ‘lookup’, ‘lookupLink’, ‘rebind’, ‘rename’, ‘unbind’]
>>>
Combine this technique with an embedded Jython interpreter to examine a running application. See the following section, “Embedding the Jython Interpreter,” for more information on embedding the Jython interpreter.
565
TEAM LinG

Chapter 22
In addition to using Jython’s interactive mode, you can also write tests in Jython.
Many organizations shy away from open-source software such as Jython. You may find it much easier to introduce Jython just for writing tests, something that will not go into production. Once your organization gains some experience with Jython, people may be more receptive to using Jython in more areas.
The examples so far have all used the jython script to run Jython scripts, except for the PyServlet servlet example. With the PyServlet class, you have a Java class with the Jython interpreter. You can add the Jython interpreter to your own classes as well.
Embedding the Jython Interpreter
By embedding the Jython interpreter in your own Java classes, you can run scripts from within your application, gaining control over the complete environment. That’s important because few Java applications run from the command line.
You can find the Jython interpreter in the class org.python.util.PythonInterpreter.
You can use code like the following to initialize the Jython interpreter:
Properties props = new Properties();
props.put(“python.home”, pythonHome);
PythonInterpreter.initialize(
System.getProperties(),
props,
new String[0]);
interp = new PythonInterpreter(null, new PySystemState());
Note that this is Java code, not Python code.
You must set the python.home system property.
Calling Jython Scripts from Java
After initializing the interpreter, you can execute a Jython script with a call to the execfile method. For example:
interp.execfile(fileName);
You need to pass the full name of the file to execute. You can see this in action with the following example.
566 |
TEAM LinG |

Integrating Java with Python
Try It Out |
Embedding Jython |
Enter the following Java program and name the file JyScriptRunner.java:
package jython;
import java.util.Properties;
import org.python.util.PythonInterpreter; import org.python.core.PySystemState;
/**
* Runs Jython scripts. */
public class JyScriptRunner {
private PythonInterpreter interp;
/**
* Initializes the Jython interpreter. */
public void initialize(String pythonHome) { Properties props = new Properties();
props.put(“python.home”, pythonHome);
PythonInterpreter.initialize(
System.getProperties(),
props,
new String[0]);
interp = new PythonInterpreter(null, new PySystemState());
}
/**
* Runs the given script. */
public void run(String fileName) { interp.execfile(fileName);
}
public static void main(String[] args) { String fileName = args[0];
JyScriptRunner runner = new JyScriptRunner();
String pythonHome = System.getProperty(“python.home”);
runner.initialize(pythonHome);
runner.run(fileName);
}
}
567
TEAM LinG

Chapter 22
Because this is a Java program, you will need to compile the program with a command like the following:
$ javac -classpath ./jython.jar JyScriptRunner.java
When you run this Java program, you will see output like the following:
$ java -cp ./jython.jar:. \ -Dpython.home=”/Users/ericfj/Documents/java/jython-2.1” \ jython.JyScriptRunner 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
This example runs the jystring.py example script. You will need to change the -Dpython.home setting to the location where you have installed Jython. Also change the ./jython.jar to the location where you have the file jython.jar.
How It Works
The program expects the caller to pass two values: the setting for the python.home system property and the name of a script to execute. You must have the jython.jar located in the current directory (or change the command line to refer to the location of your jython.jar file).
The JyScriptRunner class includes a main method, called when you run the program. The main method extracts the system property python.home as well as the filename from the command line (held in the args array). The main method then instantiates a JyScriptRunner object.
The main method initializes the JyScriptRunner object and then calls the run method to execute the script. Any errors encountered in the Jython script will result in exceptions that stop the program.
This is probably about the simplest Jython interpreter you can create. In your applications, you’ll likely want to control the location of the Python home directory, perhaps placing this under an application directory.
Compiling Python Code to Java
You can use the jythonc script to compile your Jython code into Java code, and then, into Java .class files. At its simplest, you can call jythonc with the following arguments:
jythonc --package package_name file.py
568 |
TEAM LinG |

Integrating Java with Python
This will create a directory called jpywork, and inside that directory, .java and .class files. For example, you can compile the jystring.py script introduced previously in this chapter with a command like the following:
$ jythonc --package jy jystring.py processing jystring
Required packages: java.lang
Creating adapters:
Creating .java files: jystring module
Compiling .java to .class...
Compiling with args: [‘/System/Library/Frameworks/JavaVM.framework/Versions/1.4.2/Home/bin/javac’, ‘-classpath’, ‘/Users/ericfj/Documents/java/jython- 2.1/jython.jar::./hsqldb.jar:./jpywork:: /Users/ericfj/Documents/java/jython2.1/Tools/jythonc: /Users/ericfj/writing/python/chap22/.: /Users/ericfj/Documents/java/jython-2.1/Lib’,
‘./jpywork/jy/jystring.java’]
0
When complete, you should see the following files in the jpywork directory:
$ ls jpywork/jy
jystring$_PyInner.class jystring.java jystring.class
Handling Differences between C Python and Jython
The C Python platform creates a complete environment based on Python standards and conventions. Jython, on the other hand, tries to create a complete Python environment based on the Java platform. Because of this, there are bound to be differences between the two implementations. These differences are compounded when you mix Java code into your Jython scripts.
The Jython interpreter will attempt to convert Python types into the necessary Java types to call methods on Java classes. Wherever possible, the Jython interpreter tries to do the right thing, so in most cases you don’t have to pay much attention to these type conversions. If you are unsure which Python types are needed to call a particular Java method, look at the types listed in the following table.
569
TEAM LinG

Chapter 22
Python Type |
Java Type |
|
|
None |
Null |
Integer (any non-zero |
Boolean |
value is true) |
|
Integer |
short, int, long, byte |
String |
byte[], char[], java.lang.String |
String of length 1 |
Char |
Float |
float, double |
String |
java.lang.Object, converted to java.lang.String |
Any |
java.lang.Object |
Class or JavaClass |
java.lang.Class |
Array (must contain |
Array of a particular type |
objects of a given type |
|
or subclasses of the |
|
given type) |
|
|
|
For example, if a Java method expects a type of java.lang.Object and you pass a Python String, Jython will convert the Python String to a java.langString object. Jython will pass any other Python object type unchanged.
You can do many more things with Jython beyond the introduction provided in this chapter. For example, you can create classes in Jython and then call those classes from Java. (Look in the source code for the PyServlet class to see an example of this.)
Summar y
Jython provides the capability to combine the scripting power of Python with the enterprise infrastructure of Java. Using Jython can make you a much more productive Java developer, especially in organizations where Python is not accepted but Java is.
Jython allows you to do the following:
Run Python scripts from the Java platform. Because these scripts differ from Python, they are usually called Jython scripts.
Call on Java code and classes from within your scripts. This enables you to take advantage of the rich set of Java libraries from Jython scripts.
Create user interfaces with the Java Swing API. Jython scripts can use Python’s tuple and property support to dramatically reduce the code required to create Swing-based user interfaces.
Compile Jython code to Java .class files with the jythonc script.
570 |
TEAM LinG |