Home > Software Development > Java 8 New Features: Nashorn JavaScript Engine

Java 8 New Features: Nashorn JavaScript Engine

April 28th, 2014 Leave a comment Go to comments

When JavaScript was created, it had not much to do with Java. It’s named as such maybe due to the popularity of Java language at that time. But over the years, JavaScript has gained its own popularity and dominated the client side of Web applications. There are even some work for JavaScript to extend its reach to the server side, for example, Node.js.

It’s not clear how far JavaScript can go on server side, but it’s clear that JavaScript is an important programming language. For that reason, Java started to embrace it. In Java 8 release, it includes Nashorn Javascript engine which makes it easy to run JavaScript with Java. Here we just look at several samples that I wrote while learning Nashorn for different use cases.

Time to learn how to "Google" and manage your VMware and clouds in a fast and secure

HTML5 App

Running JavaScript as String in Java

The following sample just runs a simple JavaScript that prints a string of text. You can include multiple lines of scripts there. Either way there is no data passed in and out from the Java code. This is the simplest case.

package org.doublecloud.jsdemo;
 
import java.io.FileNotFoundException;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
 
public class JsDemoInLine 
{
  public static void main(String[] args) throws ScriptException, FileNotFoundException, NoSuchMethodException 
  {
    ScriptEngineManager scriptEngineManager = new ScriptEngineManager();
    ScriptEngine jse = scriptEngineManager.getEngineByName("nashorn");
    jse.eval("print('Hello DoubleCloud! - inline');");
  }
}

Running JavaScript File in Java

The above sample works with very simple JavaScript. For any longer script, it’s hard to include in Java code. More often than not, the script goes its own file for cleaner code and better separation. The following sample shows how to execute a JavaScript file:

package org.doublecloud.jsdemo;
 
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
 
public class JsDemoFile 
{
  public static void main(String[] args) throws ScriptException, FileNotFoundException, NoSuchMethodException 
  {
    ScriptEngineManager scriptEngineManager = new ScriptEngineManager();
    ScriptEngine jse = scriptEngineManager.getEngineByName("nashorn");
    System.out.println("current dir: " + new File(".").getAbsoluteFile());
    jse.eval(new FileReader("./src/org/doublecloud/jsdemo/script.js"));
  }
}

The Javascript file is a very simple one with just one line as follows. It’s in the same directory as the above Java file and that is what the path in the above Java file points to (To be sure what the current directory is, I added one line to print it out). You can of course place it elsewhere.

print("Hello DoubleCloud! - from a script file.");

Calling Java Script Functions from Java

Simply executing a JavaScript is interesting, but not enough. We want to leverage existing fuctions and invoke them from Java code. Here is a simple sample that shows how to invoke a simple fuction in JavaScript, and how to pass in the parameter and get back result.

package org.doublecloud.jsdemo;
 
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
 
public class JsDemoToCallScriptFunc 
{
  public static void main(String[] args) throws ScriptException, FileNotFoundException, NoSuchMethodException 
  {
    ScriptEngineManager scriptEngineManager = new ScriptEngineManager();
    ScriptEngine jse = scriptEngineManager.getEngineByName("nashorn");
 
    jse.eval(new FileReader("./src/org/doublecloud/jsdemo/script_func.js"));
 
    Invocable runner = (Invocable) jse;
 
    Object result = runner.invokeFunction("hi", "DoubleCloud! - via javascript function");
    System.out.println(result);
    System.out.println(result.getClass());
  }
}

Here is the JavaScript called script_func.js that comes with a simple function in it:

var hi = function(name)
{
  return 'Hi ' + name;
}

Besides printing the result, I also printed the type of the result. I’ll leave it for you to find it out by running the sample.

Calling Java from JavaScipt

Although we can easily call JavaScript function from Java, there are probably more use cases in which we call Java code from JavaScript. As strong typed language, Java is more suitable for building libraries.

Here is a quick example where we have a simple class called HelloWorld that is to be called in JavaScript:

package org.doublecloud.jsdemo;
 
public class HelloWorld 
{
  static public String sayHi(String name)
  {
    return "Hi " + name;
  }
}

Here is the JavaScript that calls the above code:

var hw = Java.type('org.doublecloud.jsdemo.HelloWorld');
 
var result = hw.sayHi("DoubleCloud - calling Java method in JS.");
print(result);

Again, we need to invoke the above JavaScript from Java. This is similar to the sample in section two.

package org.doublecloud.jsdemo;
 
import java.io.FileNotFoundException;
import java.io.FileReader;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
 
public class JsDemoFileCallJava 
{
  public static void main(String[] args) throws ScriptException, FileNotFoundException, NoSuchMethodException 
  {
    ScriptEngineManager scriptEngineManager = new ScriptEngineManager();
    ScriptEngine jse = scriptEngineManager.getEngineByName("nashorn");
    jse.eval(new FileReader("./src/org/doublecloud/jsdemo/script_call_java.js"));
  }
}

Summary

With the above four simple samples, I’ve covered 4 different basic use cases in which JavaScript and Java can work together with Nashorn engine in Java 8. With that, we can get the best of both Java and JavaScript easily.

There are even more complicated cases than these four, for example, calling Java object methods instead of static methods. I will write more samples when
I learn these tricks. Stay tuned.

  1. No comments yet.
  1. No trackbacks yet.