Scripting Java with JavaScript

Java programs run on the Java Virtual Machine, a kind of virtual computer that hides many of the differences between the different kinds of computers it’s running on. Folks have been writing implementations of other languages that run on this virtual machine for a while now – besides JVM-specific languages like Scala and Groovy, you can also get ports of existing languages like JRuby, Jython and JavaScript.

Conveniently, in the Java 6 specification (released way back in September, 2006), official scripting support is required in the javax.script package, and a slightly stripped-down build of Mozilla Rhino, the JavaScript implementation is shipped with the JVM.

I’ve been meaning to take a look at this for a while now, and I decided to use these facilities to solve a problem I was having in my MSc. project.

My project consists of runnable experiments that produce some kind of results over sets of data. I want to have fully set up experiments ready to run so that I can repeat or extend the experiment very easily without having to refer to notes or other documentation, which involves programs that accept configuration information and wire up components.

The Java code to do this kind of thing tends to be very verbose – lots of parsing, type-checking and an inability to declare simple data structures straight into code. It’s tedious to write and then hard to read afterwards. Using JavaScript to describe my experiment setup looked like a good solution.

Example: creating a data structure that provides two named date parameters in Java, as concisely as I can:

package com.crossedstreams.experiment;

import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.Map;

public class RunExperiment {
  public static void main(String[] args) throws Exception {
    SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:hh:ss");

    Map config = new HashMap();

    config.put("start", format.parse("2012-02-01 00:00:00"));
    config.put("end", format.parse("2012-02-08 00:00:00"));

    // do stuff with this config object...
  }
}

That’s a lot of code just to name a couple of dates! The amount of code involved hides the important stuff – the dates. Now, achieving the same with JavaScript…

var config = {
  start: new Date("February 1, 2012 00:00:00"),
  end: new Date("February 8, 2012 00:00:00")
}

// do stuff with this config

When there are many parameters and components do deal with, it gets tough to stay on top of. Some of what I’m doing involves defining functions to implement filters and generate new views over data elements and JavaScript helps again here letting me define my implementers inline as part of the configuration:

filter: new com.crossedstreams.Filter({
  accept: function(element) {
    return element == awesome;
  }
})

This approach isn’t without problems, for example there’s some ugliness when it comes to using Java collections in JavaScript and JavaScript objects as collections. To be expected I guess – they are different languages that work in different ways so there’s going to be some ugly at some of the interfaces, maybe even some interpretation questions that don’t have one right answer.

Nothing I’ve come up against so far can’t be fairly easily overcome when you figure it out. I think that using Java to build components to strict interfaces and then configuring and wiring them up using a scripting language like JavaScript without leaving the JVM can be a pretty good solution.