| 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 |
... ~/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)Here's the transcript of a couple of sessions with Rhino and Jython respectively:
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)
[weiqi@gao] 1 $ rhinoWe 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.
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
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 contains an embedded scripting language. This is the second big use of scripting languages.
All the scripting languages mentioned above, 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, and many more. We will not go into this other uses in this article.
js> a = java.lang.reflect.Array.newInstance(Object, 3)
js> a.length
3
>>> from jarray import array, zerosJython 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:
>>> array([1,2,3], 'i')
array([1, 2, 3], int)
>>> from java.util import HashMap
>>> a = array([HashMap(), HashMap()], HashMap)
array([{}, {}], java.util.HashMap)
>>> 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");I have found this style of exploratory program useful in rapid prototyping of ideas, in getting acquainted with new Java APIs, and in informal testing of newly developed Java classes and packages.
f.setVisible(true);
f.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
exit();
}
});
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 TurtleThe 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.
Compiled from Turtle.java
public class Turtle extends java.awt.Canvas {
public void reset();
public void move(int);
public void turn(double);
...
}
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;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!
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) {
EtchSketch f = new EtchSketch();
}
}
