IBM Skip to main content
Search for:   within 
      Search help  
     IBM home  |  Products & services  |  Support & downloads   |  My account

developerWorks > Java technology | Linux
developerWorks
Charming Jython
79 KBe-mail it!
Contents:
Getting started with Jython
Writing code directly in the source
Building global functions
Building classes
Bridging the programming languages
Resources
About the author
Rate this article
Related content:
Repls provide interactive evaluation
Charming Python series
Subscriptions:
dW newsletters
dW Subscription
(CDs and downloads)
Learn how the Java implementation of Python can aid your development efforts

Level: Introductory

Uche Ogbuji (mailto:uche.ogbuji@fourthought.com?cc=&subject=Charming Jython)
Principal Consultant, Fourthought, Inc.
6 May 2003

Jython, the 100% Pure Java implementation of the Python programming language, combines the advantages of Python and the Java virtual machine and library and serves as a handy complement to the Java platform. In this article, software consultant and frequent developerWorks contributor Uche Ogbuji introduces Jython 2.1 to Java developers by contrasting and comparing the way Python and the Java language create classes and how they use the interpreter. Uche illustrates the differences by providing samples of Java library access, as well as the Jython interpreter shell and code files.

Jython, originally known as JPython, is an all-Java application that allows developers to use the syntax and most of the features of the Python programming language. Jython is interesting to Java programmers for several reasons:

  • Jython's version of the Python interpreter shell allows convenient experimentation and exploration of ideas and APIs without having to go through the usual Java compile/run cycle.

  • Python is dynamic and generic by design, so you don't have to add these features by using complex libraries (such as those for Java reflection and introspection). This makes some sorts of development easier and is especially useful in automated testing frameworks.

  • Many developers like Python's syntax and the feel of the language; they find it a much more productive way to develop and maintain Java applications.

In this article I will introduce Jython 2.1, the most recent release, by offering some examples of accessing Java libraries, using the Jython interpreter shell, and showcasing Jython code files. You don't need to know Python to follow along, although you will have to learn the language if you plan to go much further with Jython than the basic examples in this article.

The environment I use is Red Hat 8.0 (2.4.18 kernel) and J2SE 1.4.0. On the Jython site (see Resources), take a look at the Jython platform-specific notes for more information on platform and Java environment choices for Jython users.

Note: Both the Jython and Java languages operate on the Java runtime.

Getting started with Jython
Jython is distributed as a single Java class file containing the installer. Just download jython-21.class and place the file somewhere in the CLASSPATH, then run java jython-21. Select the components you would like to install (in the examples, I chose all the defaults), accept the license (which is the open source BeOpen/CNRI license), and specify the installation directory -- the installer will take care of the rest.

If you run into problems with the installation, see the installation information page on the Jython Web site. For UNIX platforms, you may want to add the chosen Jython installation path to your PATH environment variable. You can now just type "jython" to run the interactive shell:

Listing 1. Running the Jython shell

$ jython
Jython 2.1 on java1.4.0_01 (JIT: null)
Type "copyright", "credits" or "license" for more information.
>>>

The >>> prompt allows you to enter commands and get immediate results. In Java programming, every program must define at least one class. Listing 2 illustrates a complete Java program for writing a message to the screen:

Listing 2. A complete Java program

class App
{  
  public static void main(String args[])
  {
    System.out.println("I don't like spam!");
  }
}

JPython reduces these lines to:

Listing 3. Jython reducing Java code overhead

>>> print "I don't like spam!"
I don't like spam!
>>>

The print keyword is one of the key tools, especially in the interactive shell where it immediately prints its arguments and then returns you to the shell prompt. Not only is there less code to type and debug, but you get the results right away, without having to go through a compile/run cycle. You can print multiple values at once, and use simple expressions just as easily, as shown here:

Listing 4. Print is a key Jython tool

>>> print "one plus one is", 1+1
one plus one is 2
>>>

Jython expressions are similar to Java expressions. The result of 1+1 is an integer that is coerced to a string by print and concatenated to the initial string as specified by the comma delimiter.

You don't even need much apparatus to access standard Java libraries using Jython. The following example accesses java.util.Random:

Listing 5. Accessing standard Java libraries via Jython

>>> from java.util import Random
>>> rng = Random()
>>> i = rng.nextBoolean()
>>> print i
1
>>>

Jython's import keyword is similar to the Java language version in that it makes the contents of one module available in another, but there are some syntax and behavior differences.

The example in Listing 5 above uses the related from keyword to narrow down which symbols are imported from java.util. The next line shows the creation of an instance of the Random class. No new keyword is needed, as you can see.

There is also no type declaration needed for the variable that holds the new instance. This highlights an important simplification in Jython and one benefit of its dynamic nature -- it reduces much of the need to worry about data typing.

The next line in Listing 5 demonstrates method invocation, which is just the same as in the Java language except for the lack of type declaration for the result. nextBoolean() in Java code is a boolean. Jython 2.1 does not have a boolean type (although this may soon change; Python 2.3 adds a boolean type), so it substitutes an integer of value 0 or 1. Similarly, to invoke a Java method that expects a boolean value, you pass in an integer value meeting these constraints.

You can also use the import keyword in such a way that you fully qualify the names of all symbols imported, as shown in Listing 6:

Listing 6. Import fully qualifies all imported symbol names

>>> import java.util.Random
>>> rng = java.util.Random()
>>> print rng.nextFloat()
0.9567907452583313
>>>

Jython's floating-point values are just the same as in the Java language.

Writing code directly in the source
The interpreter is handy for quick checking and prodding, but you don't have to do all your work there -- Jython also allows you to write code in source files and then run the code (though with Jython, the compilation step is optional). As an example, the following listing is a stand-alone Jython program:

Listing 7. Sample Jython program that simulates a coin toss (save in file named listing7.py)

from java.util import Random
rng = Random()

#This is a comment in Jython
print "Flipping a coin..."
if rng.nextBoolean():
    print "Came up heads"
else:
    print "Came up tails"

Let's explain the code before we explain how to run it. This example introduces if statements in Jython, one of the first things some people remark about in Jython (as well as its antecedent Python). There is no character delimiter to mark the block executed when the condition in the if statement is true (conditions in Jython do not require enclosing parentheses, as they do in Java programming). The code is merely indented to a greater degree than the surrounding code.

Blocks of code in Jython are always marked with indentation rather than, say, curly braces. Statements that introduce code bocks, such as if, end in colons. This feature of Jython means that you have to be careful when you write code because the way you indent the code can actually change the meaning. For example, Listing 8a results in a print out of only the number 3 because the two statements above it are part of an if block whose condition is never true:

Listing 8a. Indentation: Prints only "3"

if 0:
    print "1"
    print "2"
print "3"

If I merely change the indentation of one of the lines, then the numbers 2 and 3 are printed:

Listing 8b. Indentation: Prints "2" and "3"

if 0:
    print "1"
print "2"
print "3"

The indentation also has to be consistent, it has to be associated with statements that organize code into blocks, and usually it also has to control the flow of code. For example:

Listing 8c. Indentation: A syntax error

print "1"
    print "2"
print "3"

This would simply result in a syntax error because there is no controlling statement that requires a block to be separated from the rest of the code.

The use of indentation to mark code blocks is one of the more controversial features of Python and Jython, but I believe it is often an exaggerated issue. After all, it shouldn't matter if you follow good coding standards in indentation. If good coding indentation is followed, the fact that a machine enforces this rather than a peer reviewer shouldn't matter.

Furthermore, I know of no developer who notices this restriction after a few hours of using the language. It becomes second nature to indent properly. Certainly this link between indentation and syntax can cause errors that you may have not encountered before, but the lack of explicit delimiters also eliminates some errors that are common in languages that use them.

You can run the file in Listing 7 (listing7.py) without having to compile it just by invoking the filename as an argument to the jython command, as shown below:

Listing 9. Running "coin toss" without compilation

$ jython listing7.py
Flipping a coin...
Came up tails
$ 

In the previous example, $ is just the UNIX shell prompt, much like the C:\> on a Windows system. You can also compile modules into Java bytecode (.class) files using the jpythonc command, which allows you to use the java or jre command to run it directly. There are some restrictions on the Jython modules compiled in this way, but that issue is outside the scope of this article.

Building global functions
You can create global functions with ease in Jython, even though the Java language does not support global functions. You can also define global variables (usually to set up constants without having to make a class wrapper for them). For example, look at the following listing:

Listing 10. Global function returns series of numbers in string form (save in file named listing10.py)

START = 1
SPACER = " "

def CounterString(length):
    buffer = ""
    for i in range(START, length):
        buffer = buffer + str(i) + SPACER
    return buffer

print CounterString(10)

First we define two global variables used as constants in this program -- START and SPACER -- one an integer, and one a string.

Next we define a function, CounterString, using the def keyword. The function takes a single argument, an integer called length. The fact that Jython does not explicitly check that the argument is an integer is an advantage of Jython's dynamic feature; but it can also be a disadvantage because some sorts of type errors won't be caught until later than they would be in Java programming.

Notice that the function signature line ends with a colon and thus introduces a new block, marked by the indentation in the subsequent lines. The first line in this new block initializes a string buffer as an empty string. This buffer will be manipulated to yield the expected function results.

The next line creates a loop. Jython's for statement is fundamentally different from the Java language statement. In Java programming, you set up initial and termination conditions, as well as each loop step. Jython's loops always walk over a particular sequence from start to end. The sequence is usually a list, a very important data type in Jython.

A list of three strings looks like this:


["a", b", "c"]

If you want a loop over numbers from 1 to N (as we do here), you can use the function range(), which returns a list of numbers in a given range. Some experimentation at the interactive Jython prompt should help you familiarize yourself with this tool:

Listing 11. range() function examples

>>> range(5)
[0, 1, 2, 3, 4]
>>> range(1, 5)
[1, 2, 3, 4]
>>> range(1, 10, 2)
[1, 3, 5, 7, 9]
>>> range(10, 1, -3)
[10, 7, 4]

Looking back at Listing 10, each iteration of the for loop runs as a block of code that is indented an additional step from the rest of the function body. The block is a single line in which the current buffer is concatenated to the new number, which is first coerced to a string using the str() function (rather than a cast as in Java programming), then a spacer is appended. After this loop terminates, the resulting buffer is returned. Right after the function body is a line of code to test it. Again Jython allows you to do this without any special rigging, such as a main method on an application class. The output from Listing 10 is shown here:

Listing 12. Output from Listing 10

$ jython listing10.py
1 2 3 4 5 6 7 8 9 

Building classes as easily as functions
You can create a class in Jython with the same ease as creating global functions. Listing 13 offers an example:

Listing 13. A simple example of a user-defined class (save in file named listing13.py)

class Dog:
    def __init__(self, bark_text):
        self.bark_text = bark_text
        return
    
    def bark(self):
        print self.bark_text
        return

    def annoy_neighbors(self, degree):
        for i in range(degree):
            print self.bark_text
        return

print "Fido is born"
fido = Dog("Bow wow")
print "Let's hear from Fido"
fido.bark()
print "Time to annoy the neighbors"
fido.annoy_neighbors(5)

In the code above, the first line names the class, the definition of which is all one big code block.

The first method defined is a special one, the initializer (similar to a Java constructor). It is always named __init__ and is invoked whenever a new instance of the class is created. In Jython you explicitly declare the current instance being invoked (or in the case of the initializer, created) as an argument. Traditionally this argument is called self.

In the Dog initializer, the bark_text argument, a string, is stored as an instance variable using self. The method bark() does not take any explicit parameters when invoked, but you must still specify self.

The method annoy_neighbors does take a single explicit argument which is specified in addition to self and is the number of times the dog is to bark in order to annoy the neighbors. Notice how easily the code runs to deep nesting, and thus, to indentation. annoy_neighbors has a loop block within the method definition within the class definition. The code starting with print "Fido is born" again demonstrates the class. The output of Listing 13 looks like this:

Listing 14. The output from Listing 13

$ jython listing13.py
Fido is born
Let's hear from Fido
Bow wow
Time to annoy the neighbors
Bow wow
Bow wow
Bow wow
Bow wow
Bow wow

Bridging the programming languages
In this article, we've just scratched the surface of the benefits of adding Jython to your Java programming arsenal:

  • The Jython language reduces the amount of code required to perform tasks.

  • The Jython interpreter helps with rapid code development by allowing you to run code without compilation.

  • It allows you to establish global functions and variables which the Java language doesn't support.

  • It introduces dynamic typing, while using inference and casts to operate properly in the statically-typed virtual machine.

  • It introduces the use of generic datatypes (although upcoming Java versions such as Tiger have also introduced generic types).

  • It lets developers easily develop automated testing frameworks.

Through a series of examples, we've also covered some differences in syntax and typing that a developer should be aware of, including the syntactical meaning of indentation in Jython and the introduction of an integer in place of a currently non-supported boolean type.

Using Jython by no means requires that you ditch the Java language. Jython can be a very handy supplement, useful for quick inspection and prototyping, testing, and for handling a selection of coding tasks for which its approach is better suited.

Resources

  • Visit the Jython home page to download the implementation and learn more about how to use it; if you've already acquired Jython, try these resources for help with installation and platform-specific issues.

  • Jython is an implementation of the Python language; if you plan to use Jython, you will want to be familiar with the documentation and other resources hosted at Python.org.

  • The developerWorks Linux zone hosts a regular column devoted to Python, Charming Python.

  • If you're a Java beginner, the "Java language essentials" tutorial (developerWorks, November 2000) introduces the Java programming language through examples that demonstrate the syntax of the language in an object-oriented framework and standard programming practices. (Some of the examples in this article are based on examples in that tutorial.)

  • In "Diagnosing Java code: Repls provide interactive evaluation" (developerWorks, March 2002), Eric Allen delivers an example of using Jython to build an elegant repl, a "read-eval-print-loop."

  • Join the Jython-users mailing list, a great place for online help, for interactive discussions of Jython with fellow developers.

  • O'Reilly and Noel Rappin offer "Tips for Scripting Java with Jython, Part 1," which covers 11 specific features of Jython that can be particularly time saving or exciting for Java programmers.

  • Jython Essentials (Samuele Pedroni and Noel Rappin, O'Reilly, March 2002) provides a solid introduction to the Jython, numerous examples of Jython/Java interaction, and reference material on modules and libraries of use to Jython programmers. (Chapter 1 is available online.)

  • Learn to build Web and enterprise applications with Jython in Python Programming with the Java Class Libraries (Richard Hightower, Addison-Wesley/Pearson, June 2002).

  • The ActiveState Programmer Network offers two Jython resources: a simple JSP custom tag implemented in Jython and a simple Jython servlet.

  • Fourthought Inc. is a software vendor and consultancy specializing in XML solutions for enterprise knowledge management. Fourthought develops 4Suite, an open source platform for XML, RDF, and knowledge-management applications.

  • This comprehensive set of articles on developing Web services with Python can help you understand the workings of Jython development.

  • Find hundreds of other Java technology-related articles at the developerWorks Java technology zone.

About the author
Photo of Uche OgbujiUche Ogbuji is a consultant and co-founder of Fourthought, Inc., a software vendor and consultancy specializing in XML solutions for enterprise knowledge management. Fourthought has developed 4Suite, an open source platform for XML, RDF, and knowledge-management applications. Uche is a computer engineer and writer born in Nigeria; he lives and works in Boulder, Colorado. You can contact Uche at uche.ogbuji@fourthought.com.


79 KBe-mail it!

What do you think of this document?
Killer! (5) Good stuff (4) So-so; not bad (3) Needs work (2) Lame! (1)

Comments?



developerWorks > Java technology | Linux
developerWorks
  About IBM  |  Privacy  |  Terms of use  |  Contact