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.
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.
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>
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(); } } }
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>
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()
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
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 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 are closed for "Nashorn JavaScript Engine".
Nice introduction to Nashorn. Thanks.
Its always good to learn new things…
Thanks Omkar. Try your hands on Nashorn and share your experiences :-)
Yes Praveen. Keep learning and sharing.
Very nice tutorial…will definitely try this out… :)
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.
simple and very good introduction
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?
Java is surely gonna be the best in every aspect of programming language. BTW it should be Polyglot in first para I googled it. :)
Thanks Pratik, I have fixed it now.
welcome :)
Another great effort to make a nice article :) Thank you!
Hi Joe, are you currently working?
What an useful stuff. thanks a lot, good to know all these things
Nice article on JavaScript Engine. Looking forward to work with it.keep it up Joe.
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!
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
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.