Java News Brief
March 2001 Issue

Headlines: 
Java Technical Insight of the Month
    
Scripting Languages for Java
Visit  The Java News Brief Archive for past issues of the JNB.
OCI Educational Services
       
                
Java Technical Insight of the Month

Scripting Languages For Java
by Weiqi Gao Ph.D., Senior Software Engineer, Object Computing, Inc. (OCI)

Introduction

This month's Java Technical Insight brings you to the world of scripting languages.  Since this is the Java News Brief, we'll take a Java centric view and focus on two scripting language implementations that interact nicely with Java: Rhino and Jython.

A Survey of the Field

Since the release of JDK 1.0 in 1995, many popular languages have been re-implemented in Java.  These re-implementations usually give its users the ability to access any Java classes in the JVM.  Some are even capable of compiling arbitrary scripts into Java class files.  At the same time, many languages gained the ability to access the JVM and all the classes in it in their original C implementations.  Here is a partial list of languages that I have found on the internet as free software:
 
 Language  C implementation / Java Access Layer  Java Implementation
 ECMAScript  JS Engine  / LiveConnect  Rhino
 Python  Python (a.k.a. CPython) / None  Jython (formerly JPython)
 Tcl/Tk  Tcl/Tk / TclBlend  Jacl
 Perl  Perl / JPL (bundled with Perl)  None
 Scheme  Guile and others / None  Kawa, Skij, and  and more ...
 Java itself  The JDK  BeanShell, and others

Getting Started

To start using the Java implementation of a scripting language, one downloads the jar files, puts them into the CLASSPATH, and writes a shell script or two to make using the language convenient.  Jython even comes with an installer.  A portion of my CLASSPATH reads:
... ~/rhino15R2pre/js.jar:~/jython-2.0/jython.jar: ...
And I have the following shell scripts:
rhino: java org.mozilla.javascript.tools.shell.Main $* (Rhino interactive shell)
rhinoc: java org.mozilla.javascript.tools.jsc.Main $*  (Compile JavaScript code to class files)
jython: ...  (Jython interactive shell, supplied by Jython)
jythonc: ...  (Compile Python code to class files, supplied by Jython)
Here's the transcript of a couple of sessions with Rhino and Jython respectively:
[weiqi@gao] 1 $ rhino
js> importPackage(java.awt,java.awt.event)
js> for (m in AWTEvent) print("AWTEvent." + m + ": " + AWTEvent[m])
AWTEvent.ADJUSTMENT_EVENT_MASK: 256
AWTEvent.RESERVED_ID_MAX: 1999
AWTEvent.TEXT_EVENT_MASK: 1024
  ...
AWTEvent.MOUSE_EVENT_MASK: 16
js> 3 * 3 + 4 * 4 == 5 * 5
true
js> quit()

[weiqi@gao] 2 $ jython
Jython 2.0 on java1.2.2 (JIT: sunwjit)
Type "copyright", "credits" or "license" for more information.
>>> from java.util import Random
>>> r = Random()
>>> r.nextInt()
-21966670
>>> for i in range(4, 7):
...     print r.nextDouble()
...
0.22142449772414396
0.3263682239532196
0.8371217576770793
>>> ^D

We are writing JavaScript and Python code while making use of standard Java classes.  The interactivity and the economy of expression in the scripting languages account for their first big use---Exploratory Programming and Testing.

All scripting languages mentioned above have an interpreter interface that can be embedded into applications to make them scriptable by end users.  The Netscape Navigator web browser and Xalan-J XSLT processor are good examples of applications that contain an embedded scripting language.  This is the second big use of scripting languages.

Exploratory Programming and Testing

Obviously, one of the prerequisites for using a scripting language is the familiarity with the language.  Fortunately, good tutorials and users' guides exist for all of the above languages (see resources).  For the rest of this article I'll assume that you are familiar with JavaScript and Python.  And I'll explain how Rhino and Jython allows you to access arbitrary Java objects.

Rhino and LiveConnect

LiveConnect is the mechanism that JavaScript uses to access Java objects.  LiveConnect is used by both the C engine and Rhino, while Rhino contains a few more convenient functions.  Although LiveConnect relies on a set of wrapper classes to communicate between JavaScript and Java, to the user, it works almost transparently.  Let's look at some examples: Since Java arrays are not in direct correspondence to JavaScript arrays in Rhino, creating a Java array in Rhino is more complicated than in Java.  Java reflection is used to create a Java array in Rhino:
js> a = java.lang.reflect.Array.newInstance(Object, 3)
js> a.length
3

Using Jython

For the most part, accessing Java using Jython has the same feel as using Rhino.  However, since Python (the language implemented by Jython) has a richer set of features than JavaScript, Jython provides more convenience for the exploratory Java programmer.  Let's try out our Rhino examples in Jython: Jython makes creating Java arrays easier through the jarray module:
>>> from jarray import array, zeros
>>> a = array([1,2,3], 'i')
array([1, 2, 3], int)
>>> from java.util import HashMap
>>> b = array([HashMap(), HashMap()], HashMap)
array([{}, {}], java.util.HashMap)
Jython goes one step further than Rhino in JavaBeans scripting.  All properties and event listener methods can be assigned at object construction time using keyword arguments:
>>> f = Frame("A Java Frame in Jython", visible=1, windowClosing=exit)
This is roughly equivalent to the following Java code
Frame f = new Frame("A java Frame in Jython");
f.setVisible(true);
f.addWindowListener(new WindowAdapter() {
  public void windowClosing(WindowEvent e) {
    exit();
  }
});
I have found this style of exploratory programming useful in the rapid prototyping of ideas, in getting acquainted with new Java APIs, and in informal testing of newly developed Java classes and packages.

User Level Scripting of Applications

Embedding a scripting language into an application has been a winning strategy for application designers for a long time.  With the proliferation of scripting languages for the JVM, embedding one into an application becomes as easy as choosing a language and instantiating an interpreter object of the chosen language.

Issues such as the execution environment, the scoping of objects, threading and synchronization need to be considered carefully when you embed a scripting language into an application.  We will not go into detailed discussion about these issues in this article.  Instead I will restrict my attention to a very simple Java class and write a Java application around it, giving the user the power to drive the application through scripts.

The Java class I'll script is called Turtle.  It represents a point that moves on a plane, tracing its path:

[weiqi@gao] 1 $ javap Turtle
Compiled from Turtle.java
public class Turtle extends java.awt.Canvas {
    public void reset();
    public void move(int);
    public void turn(double);
    ...
}
The methods of this class do the obvious things.  However merely using objects of this class in a plain Java application isn't very exciting.  You probably prescribe a series of move() and turn() actions in Java code, compile and execute the code, and observe the resulting pattern.

To make it more interesting, I'll write an AWT application containing a Turtle, a TextArea for the user to enter scripts, and an OK button to send scripts to the interpreter.  I have chosen to use the Jython interpreter to do the job.  However, Rhino would do the job equally well.

import org.python.util.PythonInterpreter;
public class EtchSketch extends Frame implements ActionListener {
  // I want a Turtle ...
  private Turtle turtle = new Turtle();
  // ... and a TextArea, ...
  private TextArea ta = new TextArea(10, 40);
  // ... and a Button ... (register an ActionListener)
  private Button b = new Button("OK"); { b.addActionListener(this); }
  // ... and a Jython interpreter!
  private PythonInterpreter interp = new PythonInterpreter();

  public EtchSketch() {
    // Do the GUI stuff
    ...
    // Add a variable named 'turtle' to the toplevel scope of the Jython interpreter,
    // bound to the Java object turtle
    interp.set("turtle", turtle);
  }

  public void actionPerformed(ActionEvent e) {
    // When the OK button is clicked, we grab the text from the TextArea, ...
    String script = ta.getText();
    // ... execute it in the Jython interpreter, ...
    interp.exec(script);
    // ... and prepare for the next user command.
    ta.selectAll(); ta.requestFocus();
  }

  public static void main(String[] args) {
    ScriptFrame f = new ScriptFrame();
  }
}

In this application, the user can interactively enter commands to direct the turtle's movement on the Canvas.  Since the user has the turtle object, and the whole Python language at his disposal, he can do things that may surprise the original designer.  Putting myself into my user's shoes, I immediately concocted a script that, well, surprised myself!

Summary

In this article, we illustrated, in Rhino and Jython,  two ways of using Java aware scripting languages: exploratory programming and testing, and user level scripting of applications.  But we have only scratched the surface.  The scripting languages offer much more that are worth studying and using.  Visit their websites to learn more about them.

All the scripting languages mentioned, in either their C or Java implementations, have other uses that are not directly related to the Java platform.  These uses include rapid GUI application development, CGI programming, testing frameworks, even full blown application development, and many more.  The developments in this space should be interesting for Java developers to watch.

Resources

  1. Rhino is a subproject of the Mozilla project:  http://mozilla.org/rhino .
  2. The canonical JavaScript core language guide can be found here:  http://developer.netscape.com/docs/manuals/js/core/jsguide15/contents.html .
  3. Jython has it's own web site:  http://jython.org .
  4. Of course, Python information can be found at  http://python.org .
  5. The Python tutorial is a very gentle introduction to the syntax and facilities of Python:  http://pythonlabs.com/doc/current/tut/tut.html .
  6. Bruce Eckel's new book in progress, Thinking in Patterns, has a chapter on Jython:  http://www.MindView.net/TIPatterns/index.html .

OCI Educational Services               

OCI has one of the most comprehensive OO training curricula in the country.  Clients contract group training that is either taught at the client site or at the OCI Education Center in St. Louis, MO.
(click on course titles for online descriptions)



Java
Curriculum
CORBA/C++
Curriculum
Enterprise Web
Development Curriculum
Linux
Courses

XML
Courses

Course
Catalog

Open
Enrollment
Schedule

Instructor
Bios

 


Object Computing, Inc. is a Sun Authorized Java Center in St. Louis and a Member of the Object Management Group, OMG.  OCI specializes in distributed computing using object-oriented and web-enabled technologies and provides Consulting, Education, and Product Development services to clients nation-wide.  For more information contact us at 314-579-0066 (St. Louis), 480-752-0042 (Tempe) or email info.

Click here for OCI CAREER OPPORTUNITIES.

The Java News Brief is a monthly newsletter.  The purpose and intent of this publication is to advance Java, provide technical value, and to announce available OCI Java services.  If you would prefer to not receive this newsletter or would like to subscribe please click here

Copyright © 2001. Object Computing, Inc. All rights reserved.
Java and all Java-based marks are trademarks or registered trademarks of Sun Microsystems, Inc. in the United States and other countries.
Object Computing, Inc. is independent of Sun Microsystems, Inc.