Java 8 New Features: Nashorn JavaScript Engine

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.

Bothered by SLOW Web UI to manage vSphere? Want to manage ALL your VMware vCenters, AWS, Azure, Openstack, container behind a SINGLE pane of glass? Want to search, analyze, report, visualize VMs, hosts, networks, datastores, events as easily as Google the Web? Find out more about vSearch 3.0: the search engine for all your private and public clouds.

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.

This entry was posted in Software Development and tagged , , , . Bookmark the permalink. Post a comment or leave a trackback: Trackback URL.

Post a Comment

Your email is never published nor shared. Required fields are marked *

*
*

You may use these HTML tags and attributes <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

  • NEED HELP?


    My company has created products like vSearch ("Super vCenter"), vijavaNG APIs, EAM APIs, ICE tool. We also help clients with virtualization and cloud computing on customized development, training. Should you, or someone you know, need these products and services, please feel free to contact me: steve __AT__ doublecloud.org.

    Me: Steve Jin, VMware vExpert who authored the VMware VI and vSphere SDK by Prentice Hall, and created the de factor open source vSphere Java API while working at VMware engineering. Companies like Cisco, EMC, NetApp, HP, Dell, VMware, are among the users of the API and other tools I developed for their products, internal IT orchestration, and test automation.