Chapter 21. Integrating Java with Python

Java is an object-oriented programming language. Java programs are compiled from source code into byte codes. The Java runtime engine, called a Java virtual machine, or JVM, runs the compiled byte codes. Sound familiar? At an abstract level at least, Java and Python are very similar. Like Java, Python programs are compiled into byte codes, although this can be done at runtime.

Despite these similarities, some differences between the languages exist:

  • With Python, you can run scripts directly from the source code. Compiling is optional. If you don't compile your Python code in advance, the python command will take care of this for you.

  • Java syntax is based on C and C++, two very popular programming languages. This makes it easy for developers using C++ to migrate to Java. Consequently, Java is considered a more serious and businesslike language than Python.

  • Python syntax is very simple and easy to learn, but the syntax has diverged far from C.

  • With its simple syntax and built-in support for lists, dictionaries, and tuples, you'll find Python code much easier to write than Java code. Generally, Python programs require a lot less code than the corresponding Java code.

  • Java has an advantage over Python in terms of standard APIs, though. The base Java language includes a mature database API, an API for parsing XML documents, an API for remote communication, and even an API to access LDAP directory servers. You can do all of this in Python, but Python lacks the richness, and standardization, of the many Java APIs. This becomes more apparent when you write enterprise applications in Python. Java's enterprise APIs, called Java EE, enable Java to be a player in the enterprise market. Python, unfortunately, has been relegated to a minimal role in the enterprise market.

When writing enterprise applications, you'll likely need to write them in Java. Even though Python can work well in this space, Java controls the mind share for the enterprise. Luckily, you can get the best of both worlds with Jython, an implementation of Python in Java.

Jython enables you to execute Python code from within a Java virtual machine — that is, from within any Java application.

In this chapter you learn:

  • Reasons for scripting within Java applications

  • Comparing Jython with the regular C-based Python implementations

  • Installing Jython

  • Running Python scripts from Jython

  • Calling Java code from Python scripts

  • Extending Java classes with Python classes

  • Writing Java EE servlets in Python

  • Embedding the Jython interpreter in your Java applications

Note that you'll want to have some familiarity with both Java and Python to be able to integrate Python and Java.

Scripting within Java Applications

Most software developers consider Java to be a large systems programming language, a serious language for serious tasks. Python, in this way of thinking, comes from the realm of scripting languages such as Perl and Tcl. As such, many developers typically don't respect Python because scripting languages are, of course, created for people who cannot program. You know this isn't true, but the split between programming and scripting languages remains, even though Python gracefully bridges this gap.

Despite this lack of respect, scripting languages have proven to be very productive and are widely deployed as critical parts of companies small and large (and huge and gigantic, too). You can generally accomplish a lot more in less time with less code using a scripting language than you can with a system programming language like Java.

With Java applications, scripting comes in handy for a number of reasons, including the following:

  • The scripting language can act as a macro extension language. Much like Visual Basic for Applications (VBA) enables you to script extensions to Microsoft Office; you can enable users to extend your own Java applications using Jython. Complex text editors such as jEdit (www.jedit.org) enable you to write scripts in this fashion.

  • Use Jython to speed the development of Java applications. As a high-level scripting language, you can take advantage of the productivity features of Python when compared to the complexity of Java.

  • Explore and debug running systems. Using the interactive capabilities of Jython, you can explore a running Java application. You can execute code as needed, all interactively. You already take this for granted in Python, but it's something that Java just doesn't have.

  • You can script unit tests much faster than writing them in Java. Many organizations feel uncomfortable about introducing scripting languages, especially open-source ones. Using scripts for 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. 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, because 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 website 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.

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).

Running Jython Scripts

As with the python command, jython can also run your scripts, as shown in the following example.

These examples were run on Windows Vista. 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 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. 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 commands 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

Blockquote 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.

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.

Running Jython on Your Own

You don't have to use the jython script to execute Jython scripts. You can call the Jython interpreter just like any other Java application.

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="C:\jython2.5.0" 
    -classpath C:\jython2.5.0\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 Java EE 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 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.

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

Blockquote how this looks just like a Python import. You can try this out in your own scripts, as shown in the following example.

Once created, you need to place the widgets within a container. In the example script, you need to place the JButton and JLabel widgets in the enclosing JFrame widget, as shown by the following code:

frame.contentPane.add(label, BorderLayout.CENTER)
frame.contentPane.add(button, BorderLayout.WEST)

In Swing applications, you add widgets to the content pane of the JFrame, not directly to the JFrame itself.

Finally, the script makes the JFrame widget visible:

frame.setVisible(1)

Blockquote that the Java setVisible method expects a Java Boolean value, but using the Python True would be flagged as a syntax error because the Java boolean objects aren't 0 and 1, as they are in Python; they're a class that gets used sometimes, whereas 0 and 1 get used at other times in Java. This is one area where Python data types and constants are not yet mapped to their Java equivalents.

Accessing Databases from Jython

JDBC, or Java Database Connectivity, provides a set of APIs to access databases in a consistent manner. Most, but not all, differences between databases can be ignored when working with JDBC.

Python has a set of database APIs as well, as described in Chapter 14. A large difference between the Python APIs and the Java APIs is that the Java JDBC drivers are almost all written entirely in Java. Furthermore, almost all JDBC drivers are written by the database vendors. Most Python DB drivers, such as the ones for Oracle, are written in C with a Python layer on top. Most are written by third parties, and not by the database vendors. The Java JDBC drivers, then, can be used on any platform that supports Java. The Python DB drivers, though, must be recompiled on each platform and may not work on all systems that support Python.

With Jython, the zxJDBC package provides a Python DB-compliant driver that works with any JDBC driver. That is, zxJDBC bridges between the Python and Java database APIs, enabling your Jython scripts to take advantage of the many available JDBC drivers and to use the simpler Python DB APIs.

When working with JDBC drivers, you need the value of four properties to describe the connection to the database, shown in the following table.

Property

Holds

JDBC URL

Description of the connection to the database in a format defined by the driver.

User name

Name of a user who has access rights to the database.

Password

Password of the user. This is the password to the database, not to an operating system.

Driver

Name of the Java class that provides the JDBC driver.

You need to gather these four values for any database connection you need to set up using JDBC. The zxJDBC module requires these same values. To connect to a database using the zxJDBC driver, you can use code like the following:

from com.ziclix.python.sql import zxJDBC

url='jdbc:hsqldb:hsql://localhost/xdb'
user='sa'
pw=''
driver='org.hsqldb.jdbcDriver'
db = zxJDBC.connect(url, user, pw, driver)

The values shown here for the JDBC connection come from the default values for the HSqlDB database, covered in the section "Setting Up a Database," later in the chapter.

Working with the Python DB API

Once you have a connection, you can use the same techniques shown in Chapter 14. The zxJDBC module provides a DB 2.0 API-compliant driver. (Well, mostly compliant.) For example, you can create a database table using the following code:

cursor = db.cursor()

cursor.execute("""
create table user
    (userid integer,
    username varchar,
    firstname varchar,
    lastname varchar,
    phone varchar)
""")

cursor.execute("""create index userid on user (userid)""")

After creating a table, you can insert rows using code like the following:

cursor.execute("""
insert into user (userid,username,firstname,lastname,phone)
values (4,'scientist','Hopeton','Brown','555-5552')
""")

Be sure to commit any modifications to the database:

db.commit()

You can query data using code like the following:

cursor.execute("select * from user")
for row in cursor.fetchall():
    print(row)

cursor.close()

See Chapter 14 for more on the Python DB APIs.

Setting Up a Database

If you already have a database that includes a JDBC driver, you can use that database. For example, Oracle, SQL Server, Informix, and DB2 all provide JDBC drivers for the respective databases.

If you have a database set up, try to use it. If you have no database, a handy choice is HSqlDB. HSqlDB provides a small, fast database. A primary advantage of HSqlDB is that because it is written in Java, you can run it on any platform that runs Java.

See https://sourceforge.net/projects/hsqldb/files/hsqldb/hsqldb_1_8_1/ for more on the HSqlDB database. You can download this open-source free package from this site.

You'll find installing HSqlDB quite simple. Just unzip the file you download and then change to the new hsqldb directory. To run the database in server mode, with the default parameters, use a command like the following:

$ java -cp ./lib/hsqldb.jar org.hsqldb.Server -database.0 mydb -dbname.0 xdb
[Server@922804]: [Thread[main,5,main]]: checkRunning(false) entered
[Server@922804]: [Thread[main,5,main]]: checkRunning(false) exited
[Server@922804]: Startup sequence initiated from main() method
[Server@922804]: Loaded properties from
[/Users/James/writing/python/chap22/server.properties]
[Server@922804]: Initiating startup sequence...
[Server@922804]: Server socket opened successfully in 160 ms.
[Server@922804]: Database [index=0, id=0, db=file:mydb, alias=xdb]
opened successfully in 1168 ms.
[Server@922804]: Startup sequence completed in 1444 ms.
[Server@922804]: 2009-08-22 20:09:33.417 HSQLDB server 1.8.1 is online
[Server@922804]: To close normally, connect and execute SHUTDOWN SQL
[Server@922804]: From command line, use [Ctrl]+[C] to abort abruptly

You can stop this database by typing Ctrl+C in the shell window where you started HSqlDB. You now have a database that you can connect to using the default properties shown in the following table.

Property

Value

JDBC URL

driver.jdbc:hsqldb:hsql://localhost/xdb

User name

sa

Password

'' (two single quotes, an empty string)

Driver

org.hsqldb.jdbcDriver

Working with JDBC drivers requires that you add the JDBC jar or jars to the Java classpath. The jython script doesn't handle this case, so you need to modify the script. For example, to use the HSqlDB database, modify the script to add the hsqldb.jar file:

#!/bin/sh
################################################################################
# This file generated by Jython installer

java -Dpython.home=" C:\jython2.5.0" 
    -classpath 
    "C:\jython2.5.0jython.jar:$CLASSPATH:./hsqldb.jar" 
    "org.python.util.jython" "$@"

The bold text shows the additional jar file. This example assumes that the file hsqldb.jar will be located in the current directory. That may not be true. You may need to enter the full path to this jar file.

To pull all this together, try the following example, built using the HSqlDB database.

This code uses the default connection properties for HSqlDB for simplicity. In a real-world scenario, you never want to use the default user name and password. Always change the database administrator user and password. Furthermore, HSqlDB defaults to having no password for the administration user, sa (short for system administrator). This, of course, provides a large hole in security.

The following code, taken from Chapter 14, creates a new database table:

cursor = db.cursor()

cursor.execute("""
create table user
    (userid integer,
    username varchar,
    firstname varchar,
    lastname varchar,
    phone varchar)
""")

cursor.execute("""create index userid on user (userid)""")

Though SQL does not standardize the commands necessary to create databases and database tables, this table sports a rather simple layout, so you should be able to use these commands with most SQL databases.

The code to insert rows also comes from Chapter 14, as does the query code. In this, it is Python, with the DB 2.0 API, that provides this commonality. The Jython zxJDBC module follows this API. For example, the code to query all the rows from the user table follows:

cursor = db.cursor()

cursor.execute("select * from user")
for row in cursor.fetchall():
    print(row)

cursor.close()

The zxJDBC module, though, extends the Python DB API with the concept of static and dynamic cursors. (This ties to the concepts in the java.sql.ResultSet API.) In the Python standard API, you should be able to access the rowcount attribute of the Cursor object. In Java, a ResultSet may not know the full row count for a given query, which may have returned potentially millions of rows. Instead, the JDBC standard allows the ResultSet to fetch data as needed, buffering in the manner determined by the database vendor or JDBC driver vendor. Most Java code that reads database data will then iterate over each row provided by the ResultSet.

To support the Python standard, the zxJDBC module needs to read in all the rows to properly determine the rowcount value. This could use a huge amount of memory for the results of a query on a large table. This is what the zxJDBC documentation calls a static database cursor.

To avoid the problem of using too much memory, you have the option of getting a dynamic cursor. A dynamic cursor does not set the rowcount value. Instead, a dynamic cursor fetches data as needed. If you request a dynamic cursor, you cannot access the rowcount value, but, you can iterate through the cursor to process all the rows returned by the query. To request a dynamic cursor, pass a 1 to the cursor method:

cursor = db.cursor(1)

Dynamic cursors are not part of the Python DB API, so code using this technique will not work with any DB driver except for the Jython zxJDBC driver.

Database access is essential if you are writing enterprise applications. You also need it to be able to create robust web applications.

Writing Java EE Servlets in Jython

Most Java development revolves around enterprise applications. To help (or hinder, depending on your view), Java defines a set of standards called Java EE, or Java Platform Enterprise Edition. The Java EE standards define an application server and the APIs such a server must support. Organizations can then choose application servers from different vendors, such as WebSphere from IBM, WebLogic from Bea, JBoss from the JBoss Group, and Tomcat from the Apache Jakarta project. Java developers write enterprise applications that are hosted on one of these application servers.

A servlet is defined as a small server-based application. The term servlet is a play on applet, which describes a small application. Because in the Java arena applets always run on the client, the server equivalent needed a new name, hence servlet. Each servlet provides a small piece of the overall application, although the term small may be defined differently than you are used to, because most enterprise applications are huge.

Within a Java EE application server, servlets are passive request-response applications. The client, typically a web browser such as Internet Explorer or Firefox, sends a request to the application server. The application server passes the request to a servlet. The servlet then generates the response, usually an HTML document that the server sends back to the client. In virtually all cases, the HTML document sent back to the client is created dynamically. For example, in a web ordering system, the HTML document sent back may be the results of a search or the current prices for a set of products.

The benefit of writing servlets is that Java EE provides a well-defined API for writing your servlets, and multiple vendors support this API. Contrast this situation with the Python situation where you can choose from many Python Web APIs, but you won't find anywhere near the vendor support you find in the Java EE arena.

With Jython, you can write Java servlets in Python, simplifying your work immensely. To do so, though, you need an application server that supports servlets.

Setting Up an Application Server

If you already have a Java EE application server, use that. If not, try Tomcat. Tomcat, from the Apache Jakarta project, provides a free open-source servlet engine (called a servlet container in Java EE-speak).

Download Tomcat from http://jakarta.apache.org/tomcat/. To install, unzip the file you downloaded in a directory. You should see a Tomcat directory based on the version you downloaded, such as jakarta-tomcat-6.0.20. Change to this directory. In this directory, you will see a number of files and subdirectories. The two most important subdirectories are bin, which contains scripts for starting and stopping Tomcat, and webapps, which is where you need to place any Jython scripts you create (in a special subdirectory covered in the next section).

To run Tomcat, change to the bin subdirectory and run the startup.sh script (startup.bat on Windows). For example:

$ ./startup.sh
Using CATALINA_BASE:  /Users/jamesp/servers/jakarta-tomcat-5.0.28
Using CATALINA_HOME:  /Users/jamesp/servers/jakarta-tomcat-5.0.28
Using CATALINA_TMPDIR: /Users/jamesp/servers/jakarta-tomcat-5.0.28/temp
Using JAVA_HOME:       /Library/Java/Home

You must ensure that the JAVA_HOME environment variable is set, or Tomcat will not start. To verify Tomcat is running, enter the following URL into a web browser: http://localhost:8080/. You should see a document like the one shown in Figure 21-2.

Figure 21-2

Figure 21.2. Figure 21-2

Once you have an application server such as Tomcat running, the next step is to deploy an application — in this case, a special Python servlet called PyServlet.

Adding the PyServlet to an Application Server

Jython includes a class called org.python.util.PyServlet that acts as a front end for Python scripts. The PyServlet class will load Python scripts, compile these scripts, and then execute the scripts as if they were Java servlets (which, in fact, they are, as shown in the following section "Extending HttpServlet").

To make all this magic work, though, you need to create a bona fide Java EE web application. Luckily, this isn't that hard. Change to the directory in which you installed Tomcat and run the following commands, which create directories:

$ cd webapps
$ mkdir jython

This command creates a directory under webapps with the name of jython. This means the name of your web application will be jython:

$ mkdir webapps/jython/WEB-INF

This command creates a WEB-INF directory. The name and case of this directory are very important. In Java EE, 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 modify a file named web.xml in the tomcat 6.0/conf directory. Enter the following text into web.xml:

<web-app>
  <servlet>
    <servlet-name>PyServlet</servlet-name>
    <servlet-class>
      org.python.util.PyServlet
    </servlet-class>
    <load-on-startup>1</load-on-startup>
    <init-param>
      <param-name>python.home</param-name>
      <param-value>c:jython-2.5</param-value>
    </init-param>
    <init-param>
      <param-name>python.path</param-name>
      <param-value>
        c:jython-2.5libsite-packages
      </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.

Next, you need to create some Python scripts within the new web application.

This chapter presents a whirlwind introduction to Java EE, a frightfully complicated subject. If you're not familiar with Java EE, you can look up more information in a Java EE tutorial, or visit http://java.sun.com/javaee/.

Extending HttpServlet

The javax.servlet.http.HttpServlet class provides the main hook for Java EE developers to create servlets. Java EE 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.

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.

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.

  • The Eclipse Integrated Development Environment, or IDE, provides excellent support for Java development. In addition, one Eclipse plugins stand out for Jython usage: PyDev, for working with Python, at http://sourceforge.net/projects/pydev/; 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.

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.

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());

Blockquote 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.

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.

Python Type

Java Type

None

Null

Integer (any non-zero value is true)

Boolean

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 objects of a given type or subclasses of the given type)

Array of a particular 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.)

Summary

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.

  • Access any database that provides a JDBC driver. The zxJDBC driver bridges from the Python DB API to the Java JDBC API.

  • Run Jython scripts as Java servlets by using the handy PyServlet class from your Java EE web applications.

  • Interactively gather information on Java classes and execute methods on those classes. This is very useful for testing.

  • Embed the Jython interpreter in your own Java classes, enabling you to execute Jython scripts and expressions from your Java code.

This chapter wraps up this tutorial on Python. The appendixes provide answers to the chapter exercises and links to Python resources.

Exercises

  1. If Python is so cool, why in the world would anyone ever use another programming language such as Java, C++, C#, Basic, or Perl?

  2. The Jython interpreter is written in what programming language? The python command is written in what programming language?

  3. When you package a Jython-based application for running on another system, what do you need to include?

  4. Can you use the Python DB driver modules, such as those described in Chapter 14, in your Jython scripts?

  5. Write a Jython script that creates a window with a red background using the Swing API.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.227.26.217