a log of my experiments with the rhino javascript engine, maybe even including getting some actual work done

Friday, October 5, 2007

getting started

Rhino is an open-source implementation of JavaScript written entirely in Java. It is typically embedded into Java applications to provide scripting to end users.

But, you can also make it work the other way around: write javascript, either in script files or interactively in the rhino shell, with the option of calling into java classes from javascript code. That way, all the goodies available in the java standard libraries, or any jars that you may feel like adding to rhino's classpath, are at your fingertips. Let's see how.

Here's the rhino download page at mozilla.org. Before that, you need java: in my case (Kubuntu Linux) that means aptitude install sun-java6-jdk. Just pull the js.jar from the downloaded rhino zip file, and you can already run java -jar js.jar to launch an interactive javascript shell in your terminal. Try typing help(); for some rather cryptic assistance. Either quit(); or end-of-file (Ctrl-D) exits rhino. java -jar js.jar -help produces a terse usage message, as you would expect.

To improve a bit on this, I pick a folder in my PATH (in this example, ~/bin), create a subfolder ~/bin/rhino and throw the js.jar there. In ~/bin, I create a launcher script for the rhino interactive shell, so I can quickly start it up by the short command js.

The js script can actually do a couple of other useful tasks for me. Here's what it currently contains:

#! /bin/bash
dir=$(dirname $0)
export CLASSPATH=${CLASSPATH}${CLASSPATH:+:}${dir}/rhino/\*
echo using CLASSPATH=$(printenv CLASSPATH) > /dev/stderr
[ "$1" = "-f" ] || { RLWRAP="rlwrap -C js" ;}
exec $RLWRAP java ${JAVAOPTS} \
org.mozilla.javascript.tools.shell.Main -strict "$@"

Ok, let's explain:
  • line 1 is pretty obvious, right?
  • line 2 lets the script know where it's located
  • line 3 allows java to find the rhino packages and classes, and maybe other jars I want to be searched for java classes I'll want to use from rhino. I take care not to obliterate any classpath that might be already set. The star means all jars found in the rhino folder will be added to the classpath. Then I echo (line 4) a reminder to myself about what's there.
  • in case you're wondering about rlwrap - of course, if you're planning to do some work at a command line, you want the line editing, history etc. features you're used to from bash, and the nifty little rlwrap command gives you that. Need I say, aptitude install rlwrap?
  • in the last line, why don't I just call java -jar .. ? Well, there's a little gotcha: if you do that, java will ignore the classpath you have so carefully set. You could work around that by using the -cp ${CLASSPATH} option to java, but I did it my way.
Voila, just chmod +x bin/js and your readline-enabled rhino shell is ready to run.


tom said...

Excelent! I wish I had known about "rlwrap" years ago...

Anonymous said...

nice! though i had to ad js.jar explicitly to the classpath. * didn't find it for some reason. here's my version:

#! /bin/bash
dir=$(dirname $0)
export CLASSPATH=${CLASSPATH}${CLASSPATH:+:}${dir}/rhino/js.jar
echo using CLASSPATH=$(printenv CLASSPATH) > /dev/stderr
[ "$1" = "-f" ] || { RLWRAP="rlwrap -C js" ;}
exec $RLWRAP java ${JAVAOPTS} org.mozilla.javascript.tools.shell.Main -strict "$@"%

Aaron said...

Wicked! I have used this post several times. Very useful. Thank you!

Anonymous said...

Thank you

Anonymous said...

Thanks! I was caught out by java -jar js.jar ignoring the CLASSPATH variable. Couldn't figure out why I couldn't access any non java.* classes until I found your post.