Quantcast
Username/Email:  Password: 

Programming Tools: Java Scripting Languages

What's new with Jython and a look at the latest Java scripting language, Groovy.


I recently returned from
JavaOne 2005 in San Francisco. The show was
impressive for a number of reasons. The attendance seemed to be about 30% larger
than last year's. The same could be said for the number of tutorials,
sessions and BOFs. For example, there were enough BOFs to run until
11:00pm at night. Many of the sessions were filled to capacity, with over
600 attendees each technical presentation.

Given my strong background in C++, I am used to a more amorphous attitude
toward languages. Therefore, I was surprised to see that there still is
a vibrancy to Java that I do not see with C++.

Among the many interesting things that I saw, two stand out: Eclipse
and the scripting language called Groovy. I already have
written
about Eclipse
, so here I simply note that Eclipse now seems
to dominate the Java IDE world. Groovy, on the other hand, is new. It
prompted me to look at Python-like scripting languages that run in a
Java environment.

In this article, I discuss
Jython and
Groovy, two scripting languages that use the Java
runtime environment. By the way, JavaScript has nothing to do with the
Java language, so it is not considered here.
Jython
Jython is an interpreter for the Python language. It is written in Java
to run under the Java VM. To handle Python built-in entities, Jython
produces Java compatible structures that it passes back and forth to the
JVM. The code below uses the Jython interactive shell, in which Jython takes the
Python built-in list structure and converts it to a Java list structure
that is then passed to the Java println function that then passes the
result to the JVM.


>>> print ['a','list','of','strings']
['a', 'list', 'of', 'strings']
>>>

Here is a simple program that uses the Java Swing library
to produce a trivial GUI application:


"""\
A simple demonstration of creating a swing tree widget from a
Python dictionary.
"""

import java
import javax
from pawt import swing
from pawt import awt

sampleData = {
  'PyObject': {
        'PyInteger':None,
        'PyFloat':None,
        'PyComplex':None,
        'PySequence': {
          'PyArray':None,
          'PyList':None,
          'PyTuple':None,
          'PyString':None,
        },
        'PyClass': {
          'PyJavaClass':None,
        },
  },
  'sys':None,
  'Py':None,
  'PyException':None,
  '__builtin__':None,
  'ThreadState':None,
}

Node = swing.tree.DefaultMutableTreeNode

def addNode(tree, key, value):
  node = Node(key)
  tree.add(node)
  if value is not None:
    addLeaves(node, value.items())

def addLeaves(node, items):
  items.sort()
  for key, value in items:
    addNode(node, key, value)

def makeTree(name, data):
  tree = Node("Sample Tree")
  addLeaves(tree, data.items())
  return swing.JTree(tree)

def exit(e): 
  java.lang.System.exit(0)

if __name__ == '__main__':
  tree = makeTree('Some JPython Classes', sampleData)
  button = swing.JButton('Close Me!', actionPerformed=exit)
  f = swing.JFrame("GridBag Layout Example");
  p = swing.JFrame.getContentPane(f)
  gb = awt.GridBagLayout()
  p.setLayout(gb)
  
  c = awt.GridBagConstraints();
  c.weightx = 1.0;
  c.fill = awt.GridBagConstraints.BOTH;
  
  gb.setConstraints(tree, c);
  c.gridx = 0;
  c.gridy = awt.GridBagConstraints.RELATIVE;
  gb.setConstraints(button, c);

  p.add(tree)
  p.add(button)
  f.pack();
  f.setSize(f.getPreferredSize());
  f.show();

Jython has two main advantages. First, the language is Python and has all
of its strengths, including clean and consistent syntax, introspection,
dynamic creation of classes, properties and attributes. Second, it runs
at the speed of the JVM. On the other hand, Jython also has two chief
weakness. First is its need to convert constantly between Python and
Java structures. Second, Jython has not received much work in recent
years. That is about to change, however; the current maintainer, Brian Zimmer,
recently received three grants to continue work on Jython.

The bottom line is if you know Python, then you know Jython. The
big gain is ready access to libraries such as Swing, awt and so on.
Groovy
Groovy is a new language based on features from Ruby, Python and
Haskell. However, its runtime environment is any JVM. The language
syntax attempts to be Java-like, while making the form of the language
much simpler. Groovy is a statically typed language, so it requires a compile
step before producing Java byte code. Groovy does not currently have
an interpreter, although it does have a shell.

Groovy documentation offers an impressive list of features:

  • Closure support
  • Native syntax for Lists and Maps
  • Groovy Markup
  • Groovy Path expression language
  • Groovlets for implementing Servlets easily in simple
    Groovy scripts
  • Groovy SQL for making SQL more Groovy
  • Groovy Beans for simpler syntax for working with
    beans
  • Groovy Template Engines which are pluggable, simple to
    use, integrate GPath and compile to bytecode
  • Ant scripting
  • Regex syntax for neater scripting with regular
    expressions
  • Operator Overloading to simplify working with datatypes
    Collections and Maps
  • Polymorphic iteration and autoboxing
  • Compiles straight to Java bytecode
  • Works cleanly with all existing Java objects and
    libraries

An interesting feature of Groovy is found its definition and use of closure:

A closure in Groovy is an anonymous chunk of code surrounded by braces
that takes zero, one or more arguments, returns a value, and can reference
and use variables declared in its surrounding lexical scope (i.e., the
scope at its definition point). A closure is like an anonymous inner class
in Java. It is often used in the same way. However, Groovy closures are
more powerful and often more convenient to specify and use.

Groovy's uses Java's standard types for things such as dictionaries and
lists. This means no translation is needed between Groovy code
and the JVM. This may improve execution time, depending on the application.
Closures and Anonymous Classes
Groovy's documentation provides an example that illustrates
the benefits of using closures in place of anonymous classes. Using an
anonymous class, we can write:


Button b = new Button ("Push Me");
  b.onClick (new Action() {
    public void execute (Object target)
    {
      buttonClicked();
    }
  });

Using a closure, this becomes:


Button b = new Button ("Push Me");
  b.onClick { buttonClicked() }

Another nice feature of Groovy is its "each" operator, which is used to
iterate over a collection:



SomeCollection stuff = new SomeCollection();
  stuff.each() someClosure

// for example:

def myList = [1,2,4,5,6]
myList.each { println it }  // where 'it' is current collection item

// outputs:

1
2
3
4
5
6

Groovy also has built-in structured "builders" for languages such as XML,
HTML and more. Again, a simple example illustrates how natural it is to
build structured text:


xml = new groovy.xml.MarkupBuilder()
def myList = ['acct1':['id':123111, 'type':'savings', 'balance':1234.56],
              'acct2':['id':221212, 'type':'checking', 'balance':2010.02]]
doc = xml.accounts() {
  for (entry in myList)
    acct(id:entry.key) {
      for (thing in entry.value)
        item(name:thing.key, type=thing.value)
    }
}

This small code fragment outputs:


<accounts>
  <acct id='acct2'>
    <item name='type'>checking</item>
    <item name='id'>221212</item>
    <item name='balance'>2010.02</item>
  </acct>
  <acct id='acct1'>
    <item name='type'>savings</item>
    <item name='id'>123111</item>
    <item name='balance'>1234.56</item>
  </acct>

Contrasting Jython and Groovy
Bindings

In the following example, the use of variable c is caught at compile
time in a statically defined language. Only when a is greater than b is
the use of the undefined variable, c, detected in an interpreted language.


a = 1
b = 2
if a > b:
  print c
print a,b

Another major difference between a compiled language and an interpreted
one is when things are bound to their references. In Groovy, the following
code prints "Bound to local variable":


def varA = "Bound to global variable"
def closure = { varA }
public class C {
  def varA = "Bound to local variable"
  def closure = { varA }  // bound to local varA at definition time
  public def f = closure  // f bound to local closure
};
def c = new C();          // create instance of C using new
println c.f()             // invoke f in C

in Jython, the equivalent-looking code prints "Bound to global variable":


varA = "Bound to global variable"
closure = lambda: varA
class C:
  varA = "Bound to local variable"
  closure = lambda self: varA
  f = closure
c = C()
print c.f()

For those wanting more flexibility, the Jython/Python bindings are
handier. For those wanting more stability, the Groovy implementation
may be more desirable.

Currying

Currying function arguments is another difference. Groovy has
a special "curry" mechanism to bind arguments to a function. In the
following example, "foo bar" is printed:


def c = { arg1, arg2-> println "${arg1} ${arg2}" }
def d = c.curry("foo")
d("bar")

Jython inherits Python's natural ability to curry arguments using a
number of techniques. One is:


def c(arg1, arg2): print arg1,arg2
def d(arg2): c("foo",arg2)
d("bar")

Maturity

Jython has been around a long time and is based on a mature language,
Python. However, its development has stalled in recent years. Groovy
is a relatively new language and thus still is developing. For example, its
error diagnostics leave a lot to be desired. Also, at the moment, Groovy's following is much
smaller than Jython's or Python's. However, both languages are picking
up development activity, so you have a chance to influence both languages
if you want to become involved.

______________________

Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

a sign of dynamic typing is

Anonymous's picture

a sign of dynamic typing is the following (groovy code):

def foo(String s) {"String"}
def foo(Object o) {"Object"}

def obj = "obj"
assert foo(obj) == "String"

Object obj2 = "obj"
assert foo(obj2) == "String"

both, obj and obj2 have the static type java.lang.Object when viewed from Java, but for the function call the type String is used, as this is the runtime/dynamic type. So Groovy does have dynamic typing.

A compile step is not a sign of the typing mechanism.

What about BeanShell?

Paulo Marquez's picture

Sometimes I wonder whether I am the only person in the world who uses BeanShell, It's a java interpreter written in java and uses java syntax (have I written "java" too many times? ;) .)

I think there are two nice advantages when using BeanShell:
1) The programmer does not have to learn new syntax.
2) If desired, a more script-like syntax can be used.

Also BeanShell scripts can have acess to every object within the host application, can acess all of the available java classes and runs at the VM speed (it just means I like it a lot :) .)

I am not trying to make a case for BeanShell, I'm just curious to know why BeanShell has not gotten more coverage in "Java Scripting Languages" articles and learn more about the comparative advantages of using a diferent approach to java scripting.

JavaScript

Brandon Keepers's picture


By the way, JavaScript has nothing to do with the Java language, so it is not considered here.

Historically, this statement is correct, but that is about to change. Mazilla has a javascript implementation in Java called Rhino that is slated to be included in the next major release of the JVM. And we had just convinced everyone that Java and JavaScript are not the same....

NetRexx

Dennis Decker Jensen's picture

Nice Article! I couldn't help but think about NetRexx which is Rexx built for a JVM. Rexx is an old classic scripting language from mainframes, OS/2, Amiga, Unix (sic!). It would be nice to also hear about Rexx's uses in this context, i.e. JVM scripting languages!

Ciao!

Good article. About your ver

Anonymous's picture

Good article. About your very last sentence, if someone wants to actually influence development and design decisions, go with groovy. Jython isn't going to be influenced by anyone, because it is meant to be an exact clone of CPython, nothing more, nothing less (same way with IronPython for .NET).

For those comfortable with statically typed languages, scala (http://scala.epfl.ch/) and nice (http://nice.sf.net/) have some really fascinating features.

Good article; a few typos

Anonymous's picture

I enjoyed the article. I had heard of Groovy, but not seen any examples. While the examples shown here are small, they do at least provide a little bit of flavor as to what the language is like.

There are some typos, however. In the section on Closures, there is obviously some markup intermixed in the first code example. Then in the immediately following paragraph, the word "each" should have double quotes around it, but only the first one is there.

Post new comment

  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <pre> <ul> <ol> <li> <dl> <dt> <dd> <i> <b>
  • Lines and paragraphs break automatically.
  • Use to create page breaks.

More information about formatting options