Nashorn JavaScript Engine

Last modified on May 5th, 2014 by Joe.

Nashorn is a JavaScript engine, an implementation of the ECMAScript Edition 5.1 Language Specification. It comes bundled with Java SE 8. It can be used as a scripting tool along with Java to create polyglot applications.

Nashorn is one of the core features of Java 8. It can be used in two different modes command-line and embedded in Java applications. Generally command-line is used for learning purposes. In embedded mode, it is made available as part of the javax.script (JSR 223) API.

Nashorn

Before Java 8, we had Rhino engine available with JDKs. Now it is replaced with the brand new Nashorn. Nashorn is expected to be better than Rhino in performance. In Nashorn objects like window, console that are available in a browser are not available.

Interactive Command-line tool jjs

Nashorn comes with an interactive shell which interprets statements. It can be used to quickly execute a set of statements and learn the behavior. In JDK 8’s bin folder we can find a tool named “jjs”. It is used to launch the Nashorn command-line interpreter. Lets open a command-line tool and launch the jjs interpreter.

C:\>jjs
jjs> print ("Nashorn jjs Hello World!")
Nashorn jjs Hello World!
jjs>

Nashorn Embedded in Java Application

We can use the ScriptEngine API to invoke and run JavaScript via Nashorn. Earlier we have seen a tutorial to run JavaScript in Java. It uses the javax.script package. While instantiating the ScriptEngine we need to pass ‘nashorn’ as parameter to get an instance of the Nashorn engine. Then using the engine we can

package com.javapapers.java8;

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;

public class NashornJs {
	public static void main(String[] args) throws Exception {
		ScriptEngineManager scriptEngineManager = new ScriptEngineManager();
		ScriptEngine scriptEngine = scriptEngineManager
				.getEngineByName("nashorn");
		try {
			scriptEngine.eval("print('Nashorn Hello World!');");
		} catch (final ScriptException se) {
			se.printStackTrace();
		}
	}
}

Invoking Java API from within Nashorn

Java API can be directly invoked using the fully qualified name (including the package name). It is because Nashorn has defined global objects for the Java APIs in the package name.

jjs> java.lang.String.join(" ","Java","is","cool")
Java is cool
jjs>

Alternately we can use the predefined “Java” global object. It has a function named “type”, using this function we can get JavaClass for the argument passed. Argument should be a fully qualified name of a Java class.

jjs> var StringClass = Java.type("java.lang.String")
jjs> StringClass.join(" ","Java","is","cool")
Java is cool
jjs>

Instantiating a Custom Java class from Nashorn

We can also use our custom Java classes in Nashorn engine combined with JavaScript. As given in the previous code sample, we should use the same global “Java” object and its type function. We should ensure that, we have the custom class added to the Java classpath. We can create a Jar file of our custom classes and add it to the Java classpath. Refer the tutorial to add Java class or Jar file to classpath if you are a beginner.

C:\nashorn>jjs 
js> var Animal = Java.type("com.Animal") 
jjs> var animalObj = new Animal() 

Java Beans – get / set Methods handle in Nashorn

Nashorn comes with in built support for Java beans. Bean properties need not be invoked using the get / set methods, just the property can be used directly.

package com;

public class Animal {
    private String name;

    public String getName(){
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
C:\nashorn>jjs 
jjs> var Animal = Java.type("com.Animal") 
jjs> var animalObj = new Animal() 
jjs> animalObj.name = "Lion" 
Lion 
jjs> "Hi " + animalObj.name 
Hi Lion

Using Java Arrays in Nashorn

Java arrays can be accessed in Nashorn. We can use the same global variable "Java" available in Nashorn. It has a function named ‘type’ using which we can declare a Java array and do all array operations in JavaScript.

C:\>jjs 
jjs> var JavaIntArray = Java.type("int[]") 
jjs> var intArray = new JavaIntArray(3) 
jjs> intArray[0] = 10 
10 
jjs> intArray[1] = 20 
20 
jjs> intArray[2] = intArray[0] + intArray[1] 
30 
jjs>

Java Collections in Nashorn

Java collections can be used in Nashorn. We can access the Java collection elements in JavaScript, iterate over them and do all basic operations. Array instances can be created as similar to any other classes, in type function argument we should pass parameter as with square brackets (example: Java.type(“float[ ]”) ).

C:\>jjs 
jjs> var JavaArrayList = Java.type("java.util.ArrayList") 
jjs> var jsList = new JavaArrayList() 
jjs> jsList.add("Lion") 
true 
jjs> jsList.add("Tiger") 
true 
jjs> for each (var i in jsList) print(i) 
Lion 
Tiger 
jjs> jsList[0] 
Lion 
jjs> jsList[1] 
Tiger 
jjs>

Comments on "Nashorn JavaScript Engine"

  1. Omkar says:

    Nice introduction to Nashorn. Thanks.

  2. praveen says:

    Its always good to learn new things…

  3. Joe says:

    Thanks Omkar. Try your hands on Nashorn and share your experiences :-)

  4. Joe says:

    Yes Praveen. Keep learning and sharing.

  5. Alpesh says:

    Very nice tutorial…will definitely try this out… :)

  6. Omkar says:

    Interesting to see how .js can be read from Java files. Also calling Java APIs from .js file.

    https://github.com/Omkar-Shetkar/Java_Practice/blob/master/Practice_Java/src/com/test/NashornJsTest.java

    Few years back, I worked on JSP and JavaScript. I remember the pain of passing the values of form fields to Java and vice-versa. Concept of having JavaScript engine in JVM, really eases the communication between the two. It will be interesting to see how Nashorn can really be utilized in production code.

  7. Vinodh says:

    simple and very good introduction

  8. Palani Kumar says:

    Hi Joe,
    //Nashorn objects like window, console that are available in a browser are not available//

    If window and console are not available, what is the replacement for this? and what about the existing code which is using these objects?

  9. Pratik says:

    Java is surely gonna be the best in every aspect of programming language. BTW it should be Polyglot in first para I googled it. :)

  10. Joe says:

    Thanks Pratik, I have fixed it now.

  11. Pratik says:

    welcome :)

  12. Praveen says:

    Another great effort to make a nice article :) Thank you!

  13. Hari says:

    Hi Joe, are you currently working?

  14. Elan3n says:

    What an useful stuff. thanks a lot, good to know all these things

  15. Pradyumna Swain says:

    Nice article on JavaScript Engine. Looking forward to work with it.keep it up Joe.

  16. brent larsen says:

    here’s what I did to fix the lack of console.log.

    nashorn gives you a function called “print” that does basically the same thing as console.log, so…

    var console = { log: print };

    now you can console.log(“stuff”);

    cheers!

  17. Tina says:

    Hi Joe,

    The Left Menu Bar in your tutorial does not expand. Please let me know if we need to open it in a specific browser

  18. Joe says:

    Tina, presently I have disabled it. I am doing some debug/fix for a performance issue with the site. Once that is done, I will enable it back.

Comments are closed for "Nashorn JavaScript Engine".