Introducing Jython


Jython is a pure Java implementation of the popular scripting language Python. Implemented entirely in Java, Jython runs under any compliant JVM. For its part, Python is a high-level, dynamic, object-oriented scripting language that has enjoyed considerable popularity with developers from all disciplines of software engineering.

The features of the Python language enable the writing of scripts that are far shorter than the equivalent code implemented in Java. The features of the Python language include the following:

  • Support for high-level data types, making it possible to express complex operations in a single statement

  • Loose typing, so variables do not have to be declared before they are used

  • A syntax that does not rely on curly braces or semicolons, instead using indentation to group statements and newline characters for delineating statements

This melding of the J2SE platform and Python has resulted in an exciting symbiosis. Jython harnesses the strength of the Python scripting language and offers crossplatform capabilities by virtue of the JVM under which it runs. Jython is also designed to integrate with Java, making it possible to access Java classes from within a script. Consequently, developers have the best of both worlds: access to the full services of the J2SE platform as well as the extensive set of libraries Python encompasses.

Jython's features include the following:

Portability.

Jython code executes on any platform that supports a compliant JVM.

100% Java.

Anything you can do with Java, you can do with Jython. This includes the development of applets, GUIs, and J2EE components such as servlets. The only difference is that in Jython you'll do it with fewer lines of code, albeit at the expense of type safety. You can also mix and match classes between the two languages. This includes being able to subclass classes defined in Java from Jython, and vice versa.

Interpreted and compiled.

As with most scripting languages, Jython code is interpreted. Although interpreting a language does incur a cost in terms of performance, the approach allows for changes to the code to be quickly applied and tested, thus avoiding the overhead of lengthy build cycles. Despite the decreased runtime performance, interpreting code offers better productivity gains over that of compilation. However, in this regard, Jython provides a bytecode compiler for converting certain Jython classes into .class files.

Embedded.

As well as being able to share classes with Java, Jython code can be embedded within Java programs. In this way, it is possible to have Jython code execute from within a Java application in much the same way as embedded SQL.

Object-oriented.

The Python language supports object-oriented language constructs such as classes and inheritance. The language is actually multiparadigm and provides procedural language semantics, including functions and global variables.

In the next sections, we cover the major points regarding Jython and the Jython scripting language:

  • Installing and running the Jython interpreter

  • The basics of the Jython language

  • Using a Java class from within a Jython module

  • Building a user interface using Swing components

  • Writing and deploying a servlet written as a Jython script

The first step is to download and install Jython.

Installing Jython

Jython, along with a comprehensive set of documentation, is available for download from http://www.jython.org. The site details the installation steps and provides a few basic tutorials.

Note that Jython initially started out in life as JPython. The P has since been dropped in order to sidestep some tricky licensing issues. Jython is open source and available for free download and use. Nevertheless, as is the case with all software used within this book, you should carefully read the licensing terms before using any of the software covered.

Documentation

The Jython site contains information that specifically relates to Jython, and not the Python language. For extensive documentation on the Python syntax, including a library reference and complete tutorial, visit the Python Web site at http://www.python.org.


Running Scripts

There are several ways to execute Jython scripts. Starting the Jython interpreter in interactive mode allows Jython statements to be entered and executed directly from the Jython shell.

Launch the Jython interpreter using the appropriate command file found in the bin directory of the Jython installation. On a Windows platform, this is jython.bat.

Entering jython.bat at a command prompt starts Jython in interactive mode.

 Jython 2.1 on java1.4.1_02 (JIT: null) Type "copyright", "credits" or "license" for more information. >>> x = 1 >>> if x: ...   print 'Hello World' ... Hello World >>> 

The interpreter accepts commands at the primary prompt, identified by the three greater-than signs: >>>. The secondary prompt accepts continuation commands and is identified by three dots: ....

Jython also executes Jython statements as scripts and exits the interpreter on completion. Jython script files typically have an extension of .py, and are submitted to the Jython interpreter for execution from the command line:

 jython myscript.py 

Now that we know how to run Jython programs and execute Jython statements, let's examine the rudimentary elements of the Jython language.

The Jython Language

To appreciate the brevity of the Jython syntax, we look at a complete example that demonstrates reading from a file. Manipulating files and file contents is a common use for scripting languages, so it is a good place to start. Here, the code opens a text file and displays the length of each word within the file.

 f=open('sample.txt') for word in f.read().split():   print word, len(word) f.close() 

The code shown isn't a code snippet; it is a complete example. Firing up the Jython interpreter and entering the above statements gives the following output:

 Monty 5 Python's 8 Flying 6 Circus 6 

Notice that it isn't necessary to define a class or even a main method. Furthermore, Jython's type-less syntax means the example is devoid of any type declarations, keeping the code very succinct. Statements are also grouped by indentation and not by curly braces, as in Java, thereby keeping the script short and concise.

Note

Python isn't named after a snake but after the famous BBC comedy Monty Python's Flying Circus.


The file parsing example relies on Jython's intrinsic support for compound data types such as lists and maps. The strip() function in the example transforms the contents of the file from a string to a list. The for statement then iterates over the elements of the list.

List processing is a powerful concept in Jython, making for a highly expressive syntax. Defining both lists and maps in Jython is very easy. Note Jython uses the term dictionary for lists that hold key/value pairs.

 list = ['The', 'Life', 'of', 'Brian'] map = {10: 'The', 20:'Meaning', 30:'of', 40:'Life'} 

The same declarations in Java are slightly more verbose:

 List list = new LinkedList(); list.add("The"); list.add("Life"); list.add("of"); list.add("Brian"); Map map = new HashMap(); map.put(new Integer(10), "The"); map.put(new Integer(20), "Meaning"); map.put(new Integer(30), "of"); map.put(new Integer(40), "Life"); 

Jython wouldn't be object-oriented without the ability to define classes. Here is a class declaration of type Customer, with methods update() and total().

 # Customer class declaration # class Customer:   def update(self, value):     self.amount = value   def total(self):     return self.amount 

The def keyword defines a function or method. The self parameter is important because it represents the equivalent of the this reference in Java. Jython implicitly passes this reference each time a method on an instance of the object is called.

Note

Jython is not tied to the object-oriented paradigm, and unlike Java, allows the declaration of functions outside of the scope of a class.


Instantiating the Customer class uses another terse piece of syntax. Here is how to create an object and invoke its methods:

 obj = Customer() # Create Customer instance obj.update(10) print obj.total() 

The first line creates an instance of the Customer class. Note that there is no requirement in Jython to use Java's equivalent of the new keyword or to define the type of the object being referenced by the obj variable. Jython only discovers whether the update() and total() methods actually exist on the obj reference when the interpreter attempts to execute those lines of code.

Integration with Java

Now that you have been introduced to some of the basics of the Jython syntax, it's time to move onto something more interesting. Up until this point, all the examples could have been completed using Python, the scripting language on which Jython is based.

The advantage of choosing Jython over Python, or over alternative scripting languages such as Perl or Ruby, is the ability of Jython to integrate seamlessly with existing Java classes.

To demonstrate this integration capability, we create a standard Java class and use it from a Jython script. Listing 9-1 shows the Person class.

Listing 9-1. Person Java Class Declaration
 public class Person {   private String name;   private int age;   /**    * Default constructor    */   public void Person() {   }   /*    * Getter and setter methods for class properties    */   public int getAge() {     return age;   }   public void setAge(int age) {     this.age = age;   }   public String getName() {     return name;   }   public void setName(String name) {     this.name = name;   } } 

Before the Person class can be accessed from within a Jython script, you must set the CLASSPATH environment variable so Jython can find the new classes to load. Optionally, you may write an alternate Jython startup file that sets the classpath for the interpreter accordingly.

The following is a three-line script that creates and initializes an instance of the Person class and prints out its properties.

 import Person obj = Person(name = 'Bill', age = 20) print obj.name, obj.age 

The import statement pulls the Person module into the script's namespace. If the classpath is set incorrectly, Jython will report an error at this point.

Once the class is loaded into the script, an instance of the class is created. The syntax used to initialize the object is a shorthand form. On loading the class, Jython scans the class for common patterns and can recognize JavaBean-compliant getters and setters. Jython represents these methods as properties and allows them to be set through the constructor using the notation

 Person(name = 'Bill', age = 20) 

With an instance of the Person class created, the final line prints out the two properties name and age. Again, note the convenience of being able to use property notation rather than formal method semantics.

Like Java, Jython supports inheritance, making it possible for classes to derive from both other Jython classes and Java classes. Jython supports inheritance through the syntax

 Class DerivedClass(BaseClass1, BaseClass2, BaseClassN): 

From the syntax, you can see that Jython goes beyond Java's single inheritance and supports multiple inheritance. However, when Jython classes inherit from Java classes, only a single Java class can be included in the inheritance hierarchy of a Jython class.

Listing 9-2 shows a Jython script that has the Customer class extend the Person Java class. The integration between the two class types is seamless, with the main function accessing methods from both the superclass and the deriving Customer class.

Listing 9-2. Script PersonDemo.py
 # Import Person Java class # import Person # Customer class declaration # class Customer(Person):   def update(self, value):     self.amount = value   def total(self):     return self.amount # Main function # def main():   # Create instance of Customer   #   obj = Customer(name = 'Bill', age = 20)   # Using Customer properties   #   print obj.name, obj.age   # Using Person methods   #   obj.update(99);   print obj.total() # Entry point for script # if __name__ == '__main__':   main() 

Now that we have introduced Jython's syntax and integration support for Java, the next sections provide examples of some uses for Jython scripts.

User-Interface Prototyping

Scripting languages are ideal candidates for constructing exploratory prototypes of user interfaces. Using Jython's integration capabilities with Java enables the development of user-interface prototypes with familiar Java class libraries, such as AWT and Swing. Listing 9-3 illustrates a simple user interface written in Jython and using Swing classes.

Listing 9-3. User-Interface Script listbox.py
 import java.lang as lang import javax.swing as swing import java.awt as awt def exit(event):   lang.System.exit(0) win = swing.JFrame("Jython Example", windowClosing=exit) win.contentPane.layout = awt.GridLayout(2, 1) win.contentPane.add(swing.JList(['Rapid','J2EE','Development'])) win.contentPane.add(swing.JButton('Close',actionPerformed=exit)) win.pack() win.show() 

The source file listbox.py can be executed directly from the command prompt by invoking jython listbox.py.

Figure 9-1 displays the output from the script.

Figure 9-1. Output from listbox.py.


Jython also makes a very good glue language. If server-side business components are already in place, Jython can serve as a rapid development language for building user interfaces that expose the underlying business services to the end users.

Creating a Jython Servlet

The Jython installation provides a special servlet that loads and executes Jython scripts within a Web server's servlet engine. This handy utility allows servlets to be written and deployed as Jython scripts.

Servlets are ideal candidates for use in rapid prototyping. They are easily built and deployed, and can operate independently of the server's EJB container. Using Java, however, servlets still need to be compiled, deployed, and configured. This is not so for the Jython servlet script; it only needs to be deployed.

Listing 9-4 provides an example of a servlet implemented in Jython.

Listing 9-4. Jython Servlet Script params.py
 # params.py import java, javax, sys class params(http.HttpServlet):   def doGet(self, request, response):     response.setContentType("text/html")     out = response.getWriter()     out.println("<HTML>")     out.println("<HEAD><TITLE>Jython Servlet Example</TITLE></HEAD>")     out.println("<BODY>")     out.println("<TABLE BORDER=\"1\" WIDTH=\"100%\">")     for name in request.headerNames:       out.println("<TR><TD>" + name + "</TD>");       out.println("<TD>" + request.getHeader(name) + "</TD></TR>")     out.println("</TABLE>")     out.println("</BODY></HTML>") 

Running the servlet first requires configuring and deploying Jython's PyServlet. This servlet is responsible for loading and executing Jython scripts on the fly. The servlet is configured in the Web application's web.xml deployment descriptor, as shown in Listing 9-5.

Listing 9-5. PyServlet Configuration in web.xml
 <servlet>   <servlet-name>pyservlet</servlet-name>   <servlet-class>org.python.util.PyServlet</servlet-class> </servlet> <servlet-mapping>   <servlet-name>pyservlet</servlet-name>   <url-pattern>*.py</url-pattern> </servlet-mapping> 

You can test out the Jython servlet with a suitable servlet container such as Apache's Tomcat. First, create a new directory structure for the servlet under the webapps directory: <TOMCAT_HOME>/webapps/<context>. If necessary, copy one of the example Web applications that come with the Tomcat installation.

Modify the web.xml deployment descriptor so it contains an entry for PyServlet, as shown in Listing 9-5. You also need to copy jython.jar to the lib directory of the Web application: <context>/WEB-INF/lib. The jython.jar is needed to load the Jython interpreter. Alternatively, the servlet parameter python.home can be set, which specifies the location of the jython.jar. If this parameter is not defined in the deployment descriptor, PyServlet assumes <context>/WEB-INF/lib by default.

The final step is to copy the Jython script, in this case, params.py, into the newly created <context> directory structure. Start Tomcat and test the servlet by accessing

 http://<host_name>:8080/<context>/params.py 

Figure 9-2 shows the output from the servlet.

Figure 9-2. Output from servlet params.py.


Jython is not the only scripting language to provide such good support for Java. Another scripting language worthy of consideration is Groovy, a Java-centric scripting language that is rapidly growing in popularity.



    Rapid J2EE Development. An Adaptive Foundation for Enterprise Applications
    Rapid J2EEв„ў Development: An Adaptive Foundation for Enterprise Applications
    ISBN: 0131472208
    EAN: 2147483647
    Year: 2005
    Pages: 159
    Authors: Alan Monnox

    flylib.com © 2008-2017.
    If you may any questions please contact us: flylib@qtcs.net