Running JavaScript using Apache Ant & Mozilla Rhino

Saturday, August 27, 2011 Posted by Ruslan Matveev
Apache Ant can be used for many different tasks, today I will describe you, how to set it up in combination with Mozilla Rhino JavaScript engine, to perform various tasks such as automation, data processing or any other task that can be expressed in terms of server side JavaScript. This will also give you a short introduction to Apache Ant build tool (in case if you're not familiar with it), that will be used in many other examples in the future.

First of all you'll need Apache Ant to be installed on your system, please follow the instructions on this page to get it up and running. After it's installed, you can test it by running simple build script. Create an XML - document, name it "build.xml" and paste following code snippet into it:

<?xml version="1.0" encoding="UTF-8"?>
<project name="test" default="test" basedir=".">
    <target name="test" description="test">
        <echo>Hello world!
    </target>
</project>

Then open your console, go into the directory where your build.xml is located and type "ant". This will produce following result in the console:

C:\test>ant
Buildfile: C:\test\build.xml

test:
    [echo] Hello ant!

BUILD SUCCESSFUL
Total time: 0 seconds

C:\test>

If you see it, then it's up and running, otherwise please check Ant documentation for the list of possible problems.

Run JavaScript using Apache Ant and Mozilla Rhino

Ant itself is not very powerful thing, so we'll have to add something in order to make it more useful for us. One of the features that Ant provides you "out of box" is that it can run any Java program. Let's see how that works, by creating following build script:

<?xml version="1.0" encoding="UTF-8"?>
<project name="test" default="test" basedir=".">
    <target name="test" description="test">
        <exec executable="java">
            <arg line="-version" />
        </exec>
    </target>
</project>

This build script will invoke java with single argument "-version", and at the end it will produce following result:

C:\test>ant
Buildfile: C:\test\build.xml

test:
    [exec] java version "1.5.0_09"
    [exec] Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_09-b03)
    [exec] Java HotSpot(TM) Client VM (build 1.5.0_09-b03, mixed mode)

BUILD SUCCESSFUL
Total time: 0 seconds

C:\test>

Note that the result can be different (different java version number). Okay but how do we run JavaScript? The answer is: Mozilla Rhino.

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.

Mozilla Rhino is Java - based JavaScript engine, created by Mozilla Foundation. So let's see how we can use it in Ant. First of all you'll have to download Mozilla Rhino JavaScript engine. Unpack this, and find a file called "js.jar". Put this file in the same directory (or one of the subdirectories) where your build script is located. I recommend following structure (and this will be used in the examples below):

SOME_DIRECTORY
|
+- build.xml
+- lib
   |
   +- java
      |
      +- js.jar

Next thing is to modify our build script so it can invoke Mozilla Rhino JavaScript engine, see following code snippet:

<?xml version="1.0" encoding="UTF-8"?>
<project name="test" default="test" basedir=".">
    <!-- path to Mozilla Rhino JavaScript engine -->
    <property name="path.rhino" location="lib/java/js.jar" />
    <!-- main target -->
    <target name="test" description="test">
        <!-- invoke java -->
        <exec executable="java">
            <!-- pass arguments -->
            <arg line="-jar ${path.rhino} -e 'print(Math.random())'" />
        </exec>
    </target>
</project>

This will produce following result in the console:

C:\test>ant
Buildfile: C:\test\build.xml

test:
    [exec] 0.6276304859792549

BUILD SUCCESSFUL
Total time: 0 seconds

C:\test>

Note that the result can be different (will be different because of Math.random() result). See list of all possible options for running Mozilla Rhino JavaScript engine here. Okay so the next thing is to run your JavaScript which is located in external file. Adjust the folder structure and create a file called "test.js":

SOME_DIRECTORY
|
+- build.xml
+- lib
   |
   +- java
   |  |
   |  +- js.jar
   |
   +- js
      |
      +- test.js

Adjust your build script so it will now run JavaScript code, located in lib/js/test.js:

<?xml version="1.0" encoding="UTF-8"?>
<project name="test" default="test" basedir=".">
    <!-- path to Mozilla Rhino JavaScript engine -->
    <property name="path.rhino" location="lib/java/js.jar" />
    <!-- main target -->
    <target name="test" description="test">
        <!-- invoke java -->
        <exec executable="java">
            <!-- pass arguments -->
            <arg line="-jar ${path.rhino} -opt -1 test.js" />
        </exec>
    </target>
</project>

and put something into "test.js" file (in my case it's gonna be "print('HELLO WORLD!');"), go back to your console and type "ant" in the directory with your build.xml file, this will produce following result:

C:\test>ant
Buildfile: C:\test\build.xml

test:
    [exec] HELLO WORLD!

BUILD SUCCESSFUL
Total time: 0 seconds

C:\test>

That's it, now we can run JavaScript code in non - browser environment, which is a little bit different from what you used to have in the browser... there is no window object, there is no document object, and no DOM at all,but in the mean time there are bunch of functions available that is not present in the browser environment, for example readFile (you can use it to read files from your local hard drive, how cool is that?), also there is no restrictions on performing cross domain requests (so you can even retrieve google.com page source). You can explore all this amazing features by reading the documentation here.

Using Java to extend JavaScript

One of the most important features of Mozilla Rhino JavaScript engine is that it allows you to interact with the native Java classes, directly from your JavaScript. Check out this page for more information. So the idea is that you can use Java in your JavaScript while it's all running in Mozilla Rhino. For our use case we'll use this feature to retrieve the list of the files stored on your local hard drive. Look at the following simple example that retrieves the list of the files in the current directory:

// instantiate java.io.File class
var dirObj = new java.io.File('.');
// check if it is directory
if (dirObj.isDirectory()) {
    // get list of the files
    var files = dirObj.list();
    // get absolute path to the parent directory
    var absoluteDirPath = (dirObj.getAbsolutePath() + '');
    // walk over the array of files
    for (var c = 0; c < files.length; c++) {
        // get full path to the file
        var filePath = absoluteDirPath.concat('/', files[c].toString());
        // print it!
        print(filePath);
    }
}

And here is the result:

C:\test>ant
Buildfile: C:\test\build.xml

test:
    [exec] C:\test\./build.xml
    [exec] C:\test\./lib
    [exec] C:\test\./test.js

BUILD SUCCESSFUL
Total time: 1 second

C:\test>

Additional information

Post a Comment