Categories


Archives


Recent Posts


Categories


Javascript Command Line Scripts

astorm

Frustrated by Magento? Then you’ll love Commerce Bug, the must have debugging extension for anyone using Magento. Whether you’re just starting out or you’re a seasoned pro, Commerce Bug will save you and your team hours everyday. Grab a copy and start working with Magento instead of against it.

No Frills Magento Layout is the only Magento front end book you'll ever need. Get your copy today!

Update for 10.5 Users: While I was setting up my new laptop, I noticed that Lepord (OS X 10.5) had done away with ~/Library/Java/Extensions. It wasn’t there by default and creating it manually didn’t trigger the magic “classpath but not classpath” behavior. If you’re using 10.5 and not sure where to place your jar packages, I’d recommend the root level /Library/Java/Extensions.


One of the key reasons/results for/of (chicken/egg) of the recent buzz around web applications is the change in perspective of Javascript from a horrendous hack that the browser can call on to an actual scripting/programming language running embedded in a browser.

It turns out it’s trivial these days to run Javascript programs from the command-line. The Mozilla project offers two stand-alone Javascript runtimes. Spider Monkey, implemented in C, and Rhino, implemented in Java.

Here’s how to get up and running with Rhino on OS X. These instructions should also fly for Windows and Linux, with the various system details (classpath, etc.) swapped out. This also assumes a, more or less, stock install. If you’re a Java developer with a heavily tweaked system this may not work. However, if you’re a Java developer I trust you’ll be able to figure out what to do.

Finally, per standard internet advice, make sure you have backups before doing any of this and make sure you understand what it is you’re doing to your system before blindly running commands.

Or, be sure you’re willing to accept the consequences of not being sure about the above.

Steps

  1. Ensure the Java virtual machine is installed

  2. Download and install Rhino (js.jar)

  3. [Optional] Download and install JLine

  4. Run Hello-World.js

  5. [Optional] Create an alias

Java Virtual Machine

This should be installed by default on OS X. You can check by seeing if there’s a /Libraries/Java folder on your computer, either through the Finder, or the Terminal.

From a Terminal

$ ls -lh /Library/Java/
drwxrwxr-x   5 root  admin  170B Jan 23  2007 Extensions
lrwxr-xr-x   1 root  admin  48B Feb 19  2007 Home -> /System/Library/Frameworks/JavaVM.framework/Home

Install Rhino

Next, we’ll download and install Rhino from the Mozilla website. “Installing” here means placing the file somewhere in the Java classpath, which is nerd talk for “places the Java virtual Machine looks for stuff”

The simplest place on OS X is your user account’s Library/Java/Extensions folder. Placing Rhino in your local Extensions folder ensure that the Rhino file won’t be blown away in a future software update.

However, this folder may not exist by default on your system. You can check, once again, through the Finder or by using the Terminal.

From a Terminal

$ ls ~/Library/Java/Extensions/
ls: /Users/alanstorm/Library/Java/: No such file or directory

Note the “~”, in *nix speak this means “go to my home directory”

Crap, it looks like we don’t have this folder, we’ll need to create it manually. Do it through the Finder, or embrace the Terminal.

$ mkdir -p ~/Library/Java/Extensions/

Note the “-p”. This means “if ~/Library/ doesn’t exist, create it”
and if “~/Library/Java” doesn’t exist, create it. In other words, if
the parent folders don’t exist, create then.

Now we’re ready to download Rhino. As of this writing, the 1.6R7 version is the most up-to-date.

Extract the files from the downloaded archive and look for a file called “js.jar”. This is all you’ll want. Place this in your user account’s Library/Java/Extensions folder. As with all these steps, (and as you’re likely sick of hearing), you can do this via the Finder, or via the Terminal

From a Terminal

$ curl -LO 'ftp://ftp.mozilla.org/pub/mozilla.org/js/rhino1_6R7.zip'
[..downloading...]    

$ unzip rhino1_6R7.zip
[...lots of files you don't need...]

$ cp rhino1_6R7/js.jar ~/Library/Java/Extensions/

There you go. You’ve now done the bare minimum you’ll need to run scripts from the command line. You can test your install by running the interactive Javascript console.

$ java org.mozilla.Javascript.tools.shell.Main
Rhino 1.6 release 7 2007 08 19
js>     

You can exit the console by typing Ctrl-D.

Install Jline

The interactive Javascript console will let you run any valid javascript command.

js> sum = function(a,b){ return a+b;}

function (a, b) {
    return a + b;
}

js> sum(5,7)
12

However, the shell interface is somewhat primitive, and won’t let you use the backspace, left-arrow/right-arrow, up-arrow. Annoying. Fortunately, there’s generic Java library called Jline which implements many of the niceties found in a modern shell.

It installs just as easily as the Rhino library did and is highly recommended. Download the package from sourceforge and place the jar in your Extensions folder. As of this writing, the currenct version was .9.91.

$ curl -LO 'http://superb-west.dl.sourceforge.net/sourceforge/jline/jline-0.9.91.zip'
[..downloading...]       

$ unzip jline-0.9.91.zip 
[...lots of files you don't need...]

$ cp jline-0.9.91/jline-0.9.91.jar ~/Library/Java/Extensions/

You can now invoke the Jline aware interpreter with the following command

$ java jline.ConsoleRunner org.mozilla.javascript.tools.shell.Main

Run Hello-World.js

Create a file named Hello-World.js that contains the following Javascript program.

ALAN_STORM_COM_HELLO_WORLD = {
    message:'Hello World',
    sayIt:function (){
        print("Hello World");
    }
}

ALAN_STORM_COM_HELLO_WORLD.sayIt();

Then, run the following command while in the same directory as the file you just created.

$ java jline.ConsoleRunner org.mozilla.javascript.tools.shell.Main Hello-World.js 
Hello World

You’re probably wondering about the print function in the above example. This isn’t a part of the Javascript language, it’s something we get with Rhino. This an important distinction to understand, because the opposite is also true. Namely we don’t get the built in browser objects you might normally associate with Javascript.

If that didn’t make sense, try the following in the Javascript console.

js> print(document);     
js: "<stdin>", line 2: uncaught JavaScript runtime exception: ReferenceError: "document" is not defined.
js> alert('foo');
js: "<stdin>", line 3: uncaught JavaScript runtime exception: ReferenceError: "alert" is not defined.
js> var wtf = new XMLHttpRequest();
js: "<stdin>", line 4: uncaught JavaScript runtime exception: ReferenceError: "XMLHttpRequest" is not defined.

While this is initially disappointing, it makes sense. These are objects and functions provided by the browser. What does “document” mean when you’re running a shell script? What does alert meant?

As a consolation (or grand, depending on your point of view) prize, you can import any Java object you’d like in a Rhino script. I’m not a Java programmer and haven’t played around with this much, but here’s a quick File IO example.

Create Alias

At this point, you’re probably sick of typing in that monstrous command every-time you want to run a little javascript. You can get around this by creating an alias. Here’s what you’ll want in bash; if you’re running under a different shell than the default you can likely figure out the equivalent yourself (apologies to visitors from THE FUTURE, when bash is considered old and silly)

#alias to js interpreter 
alias js='java jline.ConsoleRunner org.mozilla.javascript.tools.shell.Main'

Add the above line to your ~/.bash_profile file, and you’ll be able to run scripts with the following (remember, you won’t see the alias until you open a new Terminal window)

$ js Hello-World.js
Hello World
Originally published October 21, 2007