Java 8 is out for past 2 months & I was just going through its new feature Nashorn which is a javascript engine bringing Java & JavaScript more closer so that we can use the features of Java in JavaScript easily, cool haan.
So I just got my hands dirty in this Nashorn a bit & below are the files which I used to check its features. Before you execute these files you need java8, Eclipse Luna is supporting Java8 but I used Netbeans 8 to check the new features.
package nashorn;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
//import java.util.Iterator;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import jdk.nashorn.api.scripting.ScriptObjectMirror;
/**
*
* @author Nitin
*/
public class Nas {
public static void main(String... args) throws ScriptException, NoSuchMethodException{
// Below we need to create one Nashorn engine to access the methods in JS
ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
try {
// Below we are giving the name & path to the JS which we want to access using the given engine
engine.eval(new FileReader("D:\\Eclipse Workspaces\\Java8\\src\\nashorn\\Dummy.js"));
} catch (ScriptException ex) {
Logger.getLogger(Nas.class.getName()).log(Level.SEVERE, null, ex);
} catch (FileNotFoundException ex) {
Logger.getLogger(Nas.class.getName()).log(Level.SEVERE, null, ex);
}
// Above created engine must be made Invocable to use it
Invocable invocable = (Invocable) engine;
// Calling the JS method fun2 & passing it the required input parameter
Object result = invocable.invokeFunction("fun2", new Date());
System.out.println(result);
System.out.println(result.getClass());
ArrayList al = new ArrayList();
al.add(1);
al.add(2);
invocable.invokeFunction("iter", al);
}
// Methods to be called from JS must be public & if using the class name to access these then such methods must be static also
public static void fun3(ScriptObjectMirror mirror) {
String[] itr = mirror.getOwnKeys(true);
System.out.println(mirror.getClassName() + ": " +
Arrays.toString(mirror.getOwnKeys(true)));
for(int i = 0; i < itr.length; i++){
System.out.println(itr[i] + " : " + mirror.get(itr[i]));
}
}
public static void fun2(Object object) {
System.out.println(object.getClass());
}
public static void fun4(ScriptObjectMirror person) {
System.out.println("Full Name is: " + person.callMember("getFullName"));
}
// Below method is called from JS using the instance of Nas class
public void instanceMethod(){
System.out.println("In the instance method");
}
}
/*
* @author Nitin
*/
// It is used to get the class type of the given Java Class
var Nas = Java.type('nashorn.Nas');
// Normal JS function having one reference to call this function
var fun1 = function(name) {
print('Hi there from Javascript, ' + name);
return "greetings from javascript";
};
var fun2 = function (object) {
print("JS Class Definition: " + Object.prototype.toString.call(object));
return object.class;
};
// method must be public & static
Nas.fun2(new Number(23));
//instantiating using the above obtained class type
var inNas = new Nas();
// Only those methods can be called which are public using the object of the class
inNas.instanceMethod();
//below will error - has no such function "instanceMethod"
// because the instanceMethod is associated with instance & not the class, normal Java rule
//Nas.instanceMethod();
// passing the whole object to the Java method
Nas.fun3({
nitin: 'agrawal',
agrawal: 'nitin'
});
// creation of the Person type class in JS
function Person(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
print("Hi in Person")
this.getFullName = function() {
return this.firstName + " " + this.lastName;
}
}
// instantiating the above class & passing that object to the Java class
var person1 = new Person("Nitin", "Agrawal");
Nas.fun4(person1);
// used to import Java classes in JS
var imports = new JavaImporter(java.io, java.lang);
// object is passed from Java code & accessed in JS here & also uses the String methods as this pkg is imported above.
// So we can also import other pkg, means multiple pkgs can be imported.
var iter = function(object){
print("Direct Access : " + object.toString().valueOf()[4]);
var List = Java.type(object.class.toString().substring(6));
var cList = new List();
cList = object;
print("Through type casting JS : " + cList.get(0));
}
// below is the use of Thread class & Runnable interface from Java
var Runnable = Java.type('java.lang.Runnable');
var Printer = Java.extend(Runnable, {
run: function() {
print(this + 'printed from a separate thread');
}
});
var Thread = Java.type('java.lang.Thread');
new Thread(new Printer()).start();
new Thread(function() {
print(this + 'printed from another thread');
}).start();
// below the instance of Date type from Java is created in JS
var Date = Java.type('java.util.Date');
var date = new Date();
date.year += 1900;
print(date.year); // 2014
// below shows that how we can bind the properties of two variables in JS
var o1 = {};
var o2 = { nitin: 'agrawal'};
Object.bindProperties(o1, o2);
print(o1.nitin); // agrawal
o1.foo = 'NIT';
print(o2.foo); // NIT
// below shows that if we are having multiple imports & we want to use some specific imported class as there can be same named class from other imported
// pkgs, then we can use the specific class like shown below.
with (imports) {
var str = new String("Nitin84");
System.out.println(str.substring(0, 5));
}
So I just got my hands dirty in this Nashorn a bit & below are the files which I used to check its features. Before you execute these files you need java8, Eclipse Luna is supporting Java8 but I used Netbeans 8 to check the new features.
package nashorn;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
//import java.util.Iterator;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import jdk.nashorn.api.scripting.ScriptObjectMirror;
/**
*
* @author Nitin
*/
public class Nas {
public static void main(String... args) throws ScriptException, NoSuchMethodException{
// Below we need to create one Nashorn engine to access the methods in JS
ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
try {
// Below we are giving the name & path to the JS which we want to access using the given engine
engine.eval(new FileReader("D:\\Eclipse Workspaces\\Java8\\src\\nashorn\\Dummy.js"));
} catch (ScriptException ex) {
Logger.getLogger(Nas.class.getName()).log(Level.SEVERE, null, ex);
} catch (FileNotFoundException ex) {
Logger.getLogger(Nas.class.getName()).log(Level.SEVERE, null, ex);
}
// Above created engine must be made Invocable to use it
Invocable invocable = (Invocable) engine;
// Calling the JS method fun2 & passing it the required input parameter
Object result = invocable.invokeFunction("fun2", new Date());
System.out.println(result);
System.out.println(result.getClass());
ArrayList al = new ArrayList();
al.add(1);
al.add(2);
invocable.invokeFunction("iter", al);
}
// Methods to be called from JS must be public & if using the class name to access these then such methods must be static also
public static void fun3(ScriptObjectMirror mirror) {
String[] itr = mirror.getOwnKeys(true);
System.out.println(mirror.getClassName() + ": " +
Arrays.toString(mirror.getOwnKeys(true)));
for(int i = 0; i < itr.length; i++){
System.out.println(itr[i] + " : " + mirror.get(itr[i]));
}
}
public static void fun2(Object object) {
System.out.println(object.getClass());
}
public static void fun4(ScriptObjectMirror person) {
System.out.println("Full Name is: " + person.callMember("getFullName"));
}
// Below method is called from JS using the instance of Nas class
public void instanceMethod(){
System.out.println("In the instance method");
}
}
/*
* @author Nitin
*/
// It is used to get the class type of the given Java Class
var Nas = Java.type('nashorn.Nas');
// Normal JS function having one reference to call this function
var fun1 = function(name) {
print('Hi there from Javascript, ' + name);
return "greetings from javascript";
};
var fun2 = function (object) {
print("JS Class Definition: " + Object.prototype.toString.call(object));
return object.class;
};
// method must be public & static
Nas.fun2(new Number(23));
//instantiating using the above obtained class type
var inNas = new Nas();
// Only those methods can be called which are public using the object of the class
inNas.instanceMethod();
//below will error - has no such function "instanceMethod"
// because the instanceMethod is associated with instance & not the class, normal Java rule
//Nas.instanceMethod();
// passing the whole object to the Java method
Nas.fun3({
nitin: 'agrawal',
agrawal: 'nitin'
});
// creation of the Person type class in JS
function Person(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
print("Hi in Person")
this.getFullName = function() {
return this.firstName + " " + this.lastName;
}
}
// instantiating the above class & passing that object to the Java class
var person1 = new Person("Nitin", "Agrawal");
Nas.fun4(person1);
// used to import Java classes in JS
var imports = new JavaImporter(java.io, java.lang);
// object is passed from Java code & accessed in JS here & also uses the String methods as this pkg is imported above.
// So we can also import other pkg, means multiple pkgs can be imported.
var iter = function(object){
print("Direct Access : " + object.toString().valueOf()[4]);
var List = Java.type(object.class.toString().substring(6));
var cList = new List();
cList = object;
print("Through type casting JS : " + cList.get(0));
}
// below is the use of Thread class & Runnable interface from Java
var Runnable = Java.type('java.lang.Runnable');
var Printer = Java.extend(Runnable, {
run: function() {
print(this + 'printed from a separate thread');
}
});
var Thread = Java.type('java.lang.Thread');
new Thread(new Printer()).start();
new Thread(function() {
print(this + 'printed from another thread');
}).start();
// below the instance of Date type from Java is created in JS
var Date = Java.type('java.util.Date');
var date = new Date();
date.year += 1900;
print(date.year); // 2014
// below shows that how we can bind the properties of two variables in JS
var o1 = {};
var o2 = { nitin: 'agrawal'};
Object.bindProperties(o1, o2);
print(o1.nitin); // agrawal
o1.foo = 'NIT';
print(o2.foo); // NIT
// below shows that if we are having multiple imports & we want to use some specific imported class as there can be same named class from other imported
// pkgs, then we can use the specific class like shown below.
with (imports) {
var str = new String("Nitin84");
System.out.println(str.substring(0, 5));
}