I just discovered the JavaScript console (jrunscript) inside JDK6. Pretty nifty for running quick-and-dirty tests. Or so I thought until I ran into a bizarre problem with that most exotic of classes, java.lang.String.

I haven't blogged for a while, but I have plausible deniability. We just got twins.

???

Today, I discovered the JavaScript console in JDK6. From a command shell, run jrunscript (assuming, of course, that you have $JAVA_HOME/bin on your path). You get a JavaScript interpreter that lets you script Java classes. For example, try this little program:

importPackage(Packages.javax.swing);
frame = new JFrame();
label = new JLabel("Hello, World");
frame.add(label);
frame.setSize(200, 100);
frame.setVisible(true);

You get a GUI "Hello, World" program. Pretty nifty--no fussing with type declarations or the dreaded public static void main.

???

It works even better inside Emacs, with shell mode.

???

I am not smart enough to get regular expressions right on the first try, and I usually write a trivial Java program, complete with public static void main, to test them out before plugging them into a bigger program. When I discovered the JavaScript console, I figured that I no longer had to do that. Just fire up jrunscript and try it out:

js> Arrays.toString("foo bar".split(" "));
script error: sun.org.mozilla.javascript.internal.EvaluatorException: The choice of Java constructor toString matching JavaScript argument types (object) is ambiguous; candidate constructors are: 
    class java.lang.String toString(long[])
    class java.lang.String toString(int[])
    class java.lang.String toString(short[])
    class java.lang.String toString(char[])
    class java.lang.String toString(byte[])
    class java.lang.String toString(boolean[])
    class java.lang.String toString(float[])
    class java.lang.String toString(double[])
    class java.lang.String toString(java.lang.Object[]) (<STDIN>#1) in <STDIN> at line number 1

Ok, whatever.

js> Arrays.asList("foo bar".split(" "));
[foo, bar]

Good--that worked. What about arbitrary white space:

js> Arrays.asList("foo bar".split("\\s+"));
[foo bar]

WTH? Why didn't it split? Do I need one backslash? Four backslashes?

js> Arrays.asList("foo bar".split("\s+"));
[foo bar]
js> Arrays.asList("foo bar".split("\\\\s+"));
[foo bar]

Arggh. Back to good old public static void main:

import java.util.*;
public class Test {
   public static void main(String[] args) throws Exception {
      System.out.println(Arrays.asList("foo bar".split("\\s+")));
   }
}

The output is, of course,

[foo, bar]

Why doesn't this work in JavaScript? Perhaps JavaScript's strings aren't the same as Java String objects? Finally, I tried

js> Arrays.asList(new java.lang.String("foo bar").split("\\s+"));
[foo, bar]

Sweet success. But I am not sure I understand what is going on.

I often hear about the productivity gains of scripting languages, but I am not left with the warm and fuzzy feeling that the JavaScript console will save me time in the future.