11
Jun
Putting the Java into Javascript With Rhino
By Joseph Montanez
0 Comment

Rhino uses the jvm to allow javascript to be embedded into java and for javascript to gain access to all those libraries java has. Much like using C to write extensions to PHP you can now use Java to write extensions to javascript. But in the interest of a Javascripter like me. I am just happy using the pure javascript. The source below is converted from java example, except its now in Javascript.

smiley.js

var awt = java.awt;
var event = awt.event;
var graphics = awt.Graphics;
var system = java.lang.System;
var smileyCanvas = new JavaAdapter(awt.Canvas, {
   paint: function (g) {
       var size = this.getSize();
       var d = Math.min(size.width, size.height);
       var ed = d / 20;
       var x = (size.width - d) / 2;
       var y = (size.height - d) / 2;
       // draw head (color already set to foreground)
       g.fillOval(x, y, d, d);
       g.setColor(awt.Color.black);
       g.drawOval(x, y, d, d);
       // draw eyes
       g.fillOval(x+d/3-(ed/2), y+d/3-(ed/2), ed, ed);
       g.fillOval(x+(2*(d/3))-(ed/2), y+d/3-(ed/2), ed, ed);
       //draw mouth
       g.drawArc(x+d/4, y+2*(d/5), d/2, d/3, 0, -180);
   }
});
smileyCanvas.setForeground(awt.Color.yellow);
var winAdapter = new JavaAdapter(event.WindowAdapter, {
   windowClosing: function (evt) {
       system.exit(0);
   }
});
var f = new awt.Frame('Have a nice day');
f.addWindowListener(winAdapter);
f.add(smileyCanvas, awt.BorderLayout.CENTER);
f.pack();
f.show();
f.setSize(new awt.Dimension(320, 240));

Download Rhino

You can grab js.jar from the mozilla site, Mozilla Rhino. When you extract the zip grab js.jar. and put it into the same directory as your javascript file i.e smiley.js.

Compile your Javascript

Now we will compile our script. In Dos or any Terminal go to the directory. If you are on windows go to Start->Run, and type "cmd" in the window or in Vista, type "cmd" in the search bar. Go to your direct with your js.jar and javascript file.
>> cd C:\where-my-work-is\
>> java -cp js.jar org.mozilla.javascript.tools.shell.Main smiley.js;

Importing Javascript Files

Rhino includes javascript files by using the function load().
// mylib.js
var hello = function () {
     print('hi');
};
//Sample.js
load('mylib.js') // Single File

hello();

Using Java classes

Using a java class is rather simple, but given that has long package paths I've used importPackage to shorten them.
importPackage(java.awt); 
var myColor = new Color(0.5, 0.5, 0.0);
// What are the rgb's ?
print(myColor);
// Let extend this
myColor.foo = function () {
     print('bar');
}

// ERROR Java class "java.awt.Color" has no public instance field or method named "foo"

Extending Java Classes Objects

Sadly if its a Java class and not a Javascript Object you cant add functions / prototype unless you use a JavaAdapter. Even then its not the class your extending its the Object.
importPackage(java.awt); 
var object = JavaAdapter(java.lang.Object);
// Let extend this
object.value = []
object.toString = function () {
     return this.values.join(', ');;
};
// or
var object = new JavaAdapter(Color, java.lang.Object, {
        values: [],
        toString: function () {
            return this.values.join(', ');
        }
});

Reusing Extended Java Objects

Once an object is created you cant call the constructor new on that object, instead you'll receive an error about it not a function. So you can just wrap a function around the object.
function JMArrayObject(arrayValues) {
    // the same as calling super()
    var object = JavaAdapter(java.lang.Object, {
        values: null,
        toString: function () {
            return this.values.join(', ');
        }
    });
    // Do your constructor stuff here
    object.values = arrayValues;
    // return the object
    return object;
}

var ao = new JMArrayObject([0.75,0.5,0.5]);
print(ao);
// Output: 0.75, 0.5, 0.5

Packaging your finished Product

Because Rhino uses java you'll need to package Rhino with your script. You can compile your script in a .class (smiley.class) without the javascript source but you still need to package Rhino with it.

2) Extract the jar

Open your terminal / console / shell, whatever and change the directory to it. Now type:
jar -xf js.jar

3) Compile your Javascript

Now we will compile our script. Type:
java org.mozilla.javascript.tools.jsc.Main -nosource -opt 9 -version 170 smiley.js;
-nosource removes the javascript source code to reduce filesize, -opt 9 sets maximum performance, and -version 170 just means use javascript 1.7

4) Create a class loader

If you downloaded the start file "smile_step_1" then take note. Create smiley.txt (filename doesn't matter) and inside smiley.txt type:
smiley

Note the extra line space in the file and whats above its needed. Also note that what ever you name your main javascript mush be used as the name above (case sensitive).

Create the executable jar

Next remove all files but not your compiled javascript class file (smiley.class), your .txt file with the class loader, and the "org" folder (as well as all of its contents inside). List should read: /smiley.class /smiley.txt /org/ Now type:
jar cmf smiley.txt smiley.jar *

Now Rejoice

Yup you did it and on your way to putting the java into javascript. Be sure to join the Rhino News Group as well as Google Group. The more you support Rhino the more contributers will, well .... contribute!

« Back to my notebook
Next Note > < Previous Note
Comment Pages: 1


esign