In a previous post I explained how to embed the Rhino JavaScript engine into a Java application. I didn’t choose the new Nashorn engine because it depended on Java 8 that was still not available. Well, Java 8 has just been released so I’ve decided to explore this new implementation.

What I have done is just to clone the previous post’s repo and then refactor it to use the new engine:

  • remove external mvn dependencies as Nashorn is native on Java 8,
  • some minor package names to be consistent,
  • and refactor the engine class from RhinoEcmaEvaluator to NashornEcmaEvaluator

Executing scripts with Nashorn

Let’s have a look how executing a script with Nashorn looks like

 

As we see, executing a script with Nashorn is a matter of two steps:

  1. get the Nashorn engine (lines 3 and 4),
  2. and execute the script on the engine (line 8).

Some considerations:

  • The EcmaValue class is not part of the Nashorn engine but my own class to wrap values that get into and out of the Ecma engine.
  • Line 7 passes Java variables to the JavaScript context (as we will see), but this step is not necessary if no binding needs to be performed.

Passing Java objects to Nashorn interpreter

The way that Nashorn handles the binding between Java and JavaScript contexts is simpler than in Rhino. There is no need to setup or manipulate JavaScript contexts and create wrapping objects, just:

  1. instantiate a Bindings object, a Map like class (line 4),
  2. add the Java objects with a proper name (line 20),
  3. and finally set the Bindings object into the engine in the proper scope (line 10).

Handling JavaScript errors

The way Nashorn handles JavaScript execution errors is similar to Rhino. The ScriptEngine#eval method throws a generic exception (an instance of ScriptException) and you must inspect its content to determine what ECMA error produced the problem.

The following snippet shows how we determine a JavaScript reference error.

 

Conclussions

  • JDK8 has been released and with it, the brand new Nashorn JavaScript engine.
  • It is the new standard Java engine (last published release of Rhino was in 2012-06-18).
  • It provides a more concise api and less boilerplate than Rhino to make the interpreter work (not necessary to handle contexts and scopes or to initialize standard JavaScript objects).

Nashorn provide many other new features that I have to explore, as for example better performance, powerful console interaction, easier Java and JavaScript api integration and other features that take advantage of new Java 8 possibilities.

5 Thoughts on “Embedding Nashorn and pass Java objects to JavaScript

  1. robert on April 7, 2014 at 10:20 am said:

    From what I read Nashorn does translate the Javascript to native byte code and then executed. Do you know if Rhino does the same?

    Some reference: http://www.takipiblog.com/2014/02/10/java-8-compiling-lambda-expressions-in-the-new-nashorn-js-engine/

    • Iván Párraga García on April 7, 2014 at 4:00 pm said:

      In fact, yes, Rhino can be set to compile to bytecode the script to be executed.

      You can set the so called “optimization level”. As this level increases, more optimizations are performed so you have more time spent on the just in time compiler but less time in JavaScript execution.

      Check Rhino’s documentation for more details at: https://developer.mozilla.org/en-US/docs/Rhino/Optimization

  2. alvaro g on April 21, 2014 at 7:05 pm said:

    You say:

    It is the new standard Java engine (last published release of Rhino was in 2012-06-18).

    Is that “the new standard javascript engine”?

    Cheers,

  3. Pingback: Ejecutando JavaScript en Java con Nashorn embebido | #SOFT #WAR #FAIR

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">

Post Navigation