jjs, which is located in
$JAVA_HOME/bin. If you plan to work with
jjs you might want to put a symbolic link for simple access:
This tutorial focuses on using nashorn from java code, so let's skip
jjs for now. A simple HelloWorld in java code looks like this:
javax.script package already known from Rhino (Javas legacy js engine from Mozilla).
The current strategy for Nashorn is to follow the ECMAScript specification. When we release with JDK 8 we will be aligned with ECMAScript 5.1. The follow up major release of Nashorn will align with ECMAScript Edition 6.
In order to call a function you first have to cast the script engine to
Invocable. The Invocable interface is implemented by the
NashornScriptEngine implementation and defines a method
Executing the code results in three lines written to the console. Calling the function
Now let's call the second function by passing arbitrary java objects:
Java.type API extension. It's similar to importing classes in java code. As soon as the java type is defined we naturally call the static method
fun1() and print the result to
sout. Since the method is static, we don't have to create an instance first.
The following java method simply prints the actual class type of the method parameter:
jdk.nashorn.internal are subject to change, so you shouldn't program against those classes in client-code:
jdk.nashorn.api. Classes from this package are intended to be used in client-code.
The next sample changes the parameter type from
When passing an object hash to this method, the properties are accessible on the java side:
lastName and method
getFullName can be called on the ScriptObjectMirror via
When passing a new person to the java method, we see the desired result on the console:
Nashorn defines various language and API extensions to the ECMAScript standard. Let's head right into the most recent features:
int array behaves like a real java int array. But additionally Nashorn performs implicit type conversions under the hood when we're trying to add non-integer values to the array. Strings will be auto-converted to int which is quite handy.
Collections and For Each
Instead of messing around with arrays we can use any java collection. First define the java type via
Java.type, then create new instances on demand.
In order to iterate over collections and arrays Nashorn introduces the
for each statement. It works just like the foreach loop in java.
Here's another collection foreach example, utilizing
Lambda expressions and Streams
Everyone loves lambdas and streams - so does Nashorn! Although ECMAScript 5.1 lacks the compact arrow syntax from the Java 8 lambda expressions, we can use function literals where ever lambda expressions are accepted.
Java types can simply be extended with the
Java.extend extension. As you can see in the next example, you can even create multi-threaded code in your scripts:
Methods and functions can either be called with the point notation or with the square braces notation.
Passing the optional parameter type
println(double) when calling a method with overloaded parameters determines the exact method to be called.
Instead of explicitly working with getters and setters you can just use simple property names both for getting or setting values from a java bean.
For simple one line functions we can skip the curly braces:
Properties from two different objects can be bound together:
I like my strings trimmed.
In case you forget where you are:
Sometimes it's useful to import many java packages at once. We can use the class
JavaImporter to be used in conjunction with the
with statement. All class files from the imported packages are accessible within the local scope of the
Some packages like
java.util can be accessed directly without utilizing
And the other way around:
super keyword doesn't exist in ECMAScript. Luckily nashorn goes to the rescue.
First we define a super type in java code:
Next we override
Runner instance: The syntax of overriding members is borrowed from javas anonymous objects.
We call the overridden method
SuperRunner.run() by utilizing the
I'm using Underscore.js a lot for my web front-ends, so let's reuse Underscore in Nashorn:
This problem can be bypassed by loading script files into a new global context:
If you're interested in writing command-line (shell) scripts with Java, give Nake a try. Nake is a simplified Make for Java 8 Nashorn. You define tasks in a project-specific
Nakefile, then run those tasks by typing
For Java Developers writing command-line scripts is easy as never before...
Keep on coding!