blob: c6657a973b18815946769e42a11470ee3ffd80d8 [file] [log] [blame]
<?php
/*******************************************************************************
* Copyright (c) 2015 Eclipse Foundation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://eclipse.org/legal/epl-v10.html
*
* Contributors:
* Eric Poirier (Eclipse Foundation) - Initial implementation
*******************************************************************************/
?>
<h1 class="article-title"><?php echo $pageTitle; ?></h1>
<p>You’ve probably read or heard about some of the key features of the
upcoming Java SE 8 and JDK 8 already:</p>
<ul>
<li>Project Lambda (JSR 335), which makes it easier to write code
for multi-core processors,</li>
<li>a set of Compact Profiles, which allow Java SE 8 implementations
to scale down easily,</li>
<li>a new Date and Time API (JSR 310), and</li>
<li>the removal of the “permanent generation” from the HotSpot JVM.</li>
</ul>
<p>All of these features were very large engineering efforts. Project
Nashorn, another key feature of JDK 8, is no exception: it
introduces a new lightweight, high-performance implementation of
JavaScript and integrates it into the JDK.</p>
<p>You may be wondering: JavaScript? In the JDK!?, so I’ll better
begin at the beginning.</p>
<h2>JavaScript on the JVM</h2>
<p>
In the beginning, there was <i>JSR 223: Scripting for the Java
Platform</i>. That JSR defined the <i>javax.script</i> API, which
was first included in the Java SE 6 platform release. The
javax.script API provides a scripting language independent way to
use such languages directly from Java. Oracle JDK 6 and JDK 7 are
co-bundled with a Mozilla Rhino based JSR 223 script engine for
JavaScript.
</p>
<p>Mozilla Rhino is an open source implementation of JavaScript
implemented in the Java programming language. It takes its name from
the rhinoceros on a cover of a popular book teaching developers how
to write code in JavaScript. Over the years, though, its performance
had fallen far behind that of other JavaScript engines. To improve
performance, Rhino would need to rewritten to fully exploit the
capabilities of the modern Java platform.</p>
<p>
Rather then undertaking a major rewrite of the very old Rhino code,
at the JVM Language Summit in 2011, Jim Laskey, Oracle’s
Multi-language Lead in the Java Language and Tools Group, announced
that Oracle was working on a fresh implementation of JavaScript for
the JVM, called <i>Nashorn</i> (‘rhinoceros’ in German). Nashorn
would be based on ECMAScript-262 Edition 5.1 language specification,
and provide an example of using new technologies in Java SE 7 like
JSR 292 and the new <i>invokedynamic</i> bytecode instruction for
low-overhead scripting language implementations.
</p>
<p>By late 2012, there was a Nashorn Project in the OpenJDK community,
and the code making up the implementation was open source. It
attracted early adopters and rapidly improved to the point of
passing all of ECMAScript compliance tests. Nashorn eventually
replaced Rhino during the development of the upcoming JDK 8 release
in 2013, and has evolved into one of the key features of that
release.</p>
<p>JavaScript, too, has evolved in the past years, and seen a lot more
use outside its original niche inside web browsers. That may make a
fully compatible, highly performant implementation of JavaScript on
the JVM increasingly appealing to Java and JavaScript developers
alike.</p>
<h2>Availability</h2>
<p>
Like all JDK 8 features, the Nashorn JavaScript engine is currently
available in binary form as part of the regularly updated JDK 8
Early Access Release binaries. You can find binaries for Microsoft
Windows, OS X, Linux and Oracle Solaris operating systems at <a
target="_blank" href="https://jdk8.java.net/">http://jdk8.java.net</a>.
</p>
<p>The open source code that Nashorn is composed of can be found in
the OpenJDK Project Nashorn Mercurial repositories.</p>
<p>
Once you install a JDK 8 Early Access Release, or build your own
installation from the source code in OpenJDK, you’ll be able to use
the Nashorn JavaScript engine through the javax.script API and the
jrunscript tool, just as you could with Rhino. In addition, Nashorn
comes with a new command line application called <i>jjs</i>, which
lives in the <i>bin</i> directory of a JDK 8 installation. The <i>jjs</i>
tool can be used to run and evaluate JavaScript programs directly,
making it easy to use JavaScript to write shell scripts, prototype
code on the command line, and even write JavaFX applications in
JavaScript.
</p>
<h2>Features</h2>
<p>While the Nashorn JavaScript engine is a drop-in replacement for
Mozilla Rhino in JDK 8, it also offers a number of additional
features that make it an attractive option for new projects being
developed in JavaScript.</p>
<h3>Interoperable</h3>
<p>Rather then being just another JavaScript engine, Nashorn provides
interoperability between the Java and JavaScript worlds. That means
your Java code can call JavaScript code, and vice versa.</p>
<p>
Nashorn provides global objects to access and instantiate Java
classes from JavaScript. Their members can be accessed using the
familiar ‘.’ notation as in Java. Getters and setters in JavaBeans
are exposed as equivalent JavaScript properties. Bounds-checked Java
arrays can be instantiated and accessed from JavaScript, while
JavaScript arrays can be converted to regular Java arrays when
needed. You can use <i>for</i> and <i>for each</i> to traverse
through both types of arrays. Strings and numbers are handled
transparently, by interpreting them as instances of the
corresponding Java classes, depending on the operation performed.
Finally, collections are interpreted as arrays.
</p>
<p>In addition, you can extend Java classes by providing a JavaScript
function that implements a new method. Nashorn can automatically
extend single abstract method classes if you provide the new
method’s implementation in the constructor. This leads to some very
compact code for action listeners, for example.</p>
<h3>Embeddable</h3>
<p>Nashorn comes included with the JDK. All you need to do to use
Nashorn is to install JDK 8, and its right there, ready for your
JavaScript code. Accordingly, it’s very easy to use Nashorn to
extend your Java applications with JavaScript code as there are no
third party libraries to track down, add to a project and keep track
of.</p>
<p>In addition, since Nashorn is written in the Java programming
language, it can be run on any supported platform for JDK 8 - that
includes tiny ARM Linux devices like the Raspberry Pi, where the
ability to use JavaScript to write parts of your application in
conjunction with Java may provide a more rapid prototyping,
development and deployment cycle.</p>
<h3>Compatible</h3>
<p>
Compatibility matters, as Java developers know very well. The
ECMAScript 5.1 standard has a corresponding test suite, available at
<a target="_blank" href="http://test262.ecmascript.org/">http://test262.ecmascript.org</a>.
Nashorn passes all the compliance tests, as compatibility has been a
primary goal of the implementation from the beginning.
</p>
<p>It’s important to note that Nashorn does not include support for a
browser plugin API, DOM/CSS or any related libraries. The goal
pursued by the Nashorn team is not to provide a fast JavaScript
implementation for a specific browser - it’s to provide a very fast
implementation for server-side JavaScript applications and scripts
embedded in Java applications.</p>
<h3>Performant</h3>
<p>
Under the hood, Nashorn uses the <i>invokedynamic</i> JVM
instruction to implement all of its invocations. That is a major
component of the comparative improvement of performance and memory
usage regarding Mozilla Rhino.
</p>
<p>Since JavaScript does not have a ‘native’ bytecode format,
JavaScript source code is first parsed to construct an immediate
representation (AST/IR). The AST/IR is then lowered to something
closer to JVM bytecode by transformation of controls, reduction of
expressions to primitive operations, and simplification of calls, to
be efficiently translated to JVM instructions, and securely loaded
into the JVM. Generated code and call history are cached by the
linker, to make lookup and invocation faster on successive relinks -
JavaScript being a dynamic language, the actual code that needs to
be ran by the JVM for a function being invoked at a given point in
the code may change over time, and need to be recompiled and
relinked. Nashorn takes care of all that under the hood using high
quality third party helper libraries.</p>
<p>It does so very efficiently - it currently performs about 2x till
10x better than Mozilla Rhino on individual JavaScript engine
benchmarks from the Octane benchmark suite.</p>
<h3>Shell Scripting</h3>
<p>
Nashorn comes with a number of small extensions to make it easier to
use JavaScript for shell scripting. They are enabled by passing the
<i>-scripting</i> flag to the <i>jjs</i> application. But if your
script starts with the shebang (#!) characters and the direct path
to the <i>jjs</i> application, you don’t need to pass the flag.
</p>
<p>
You can use string interpolation
<code>(&#36;{var})</code>
to use the values of variables or expressions to construct strings
within double quotation marks. You can also use a here document
(heredoc) to specify strings that preserve line breaks and
indentation. Environment variables, command line arguments, output
and error strings are available as global objects, as well as the
script’s exit code and a global function to run commands.
</p>
<p>Additionally, Nashorn provides several built-in functions to exit
the script, print and read lines from standard output and input,
read files, load scripts, and bind properties of objects.</p>
<h3>JavaFX</h3>
<p>
You can write JavaFX applications entirely in JavaScript using
Nashorn. In order to let the <i>jjs</i> application know that your
script is a JavaFX application, you need to pass the <i>-fx</i> flag
to it.That way, Nashorn automatically takes care of calling the
right JavaFX methods to setup the application, and eliminates the
need to provide boiler plate code.
</p>
<p>
In addition, JavaFX code can become more compact using Nashorn, as
there is no need to declare value types, import packages, use
annotations, specify a class name or declare a <i>main</i> method,
and only the JavaFX classes that are instantiated in the code have
to be declared. Given that Nashorn provides access to JavaBeans
getters and setters as JavaScript properties, and JavaScript uses
closures instead of anonymous inner classes, the corresponding
application can end up being much shorter.
</p>
<p>Finally, access to the JavaFX primary stage is provided through a
global property.</p>
<h2>Summary</h2>
<p>Nashorn is an exciting new feature in the upcoming JDK 8. It
provides a timely update of performance and capabilities of the
co-bundled JavaScript engine.</p>
<h2>Resources</h2>
<ul>
<li><a target="_blank"
href="http://openjdk.java.net/projects/nashorn/">Project Nashorn</a></li>
<li><a target="_blank"
href="http://download.java.net/jdk8/docs/technotes/guides/scripting/nashorn/toc.html">Nashorn
User Guide</a></li>
<li><a target="_blank" href="https://blogs.oracle.com/nashorn/">Nashorn
blog</a></li>
<li><a target="_blank"
href="http://download.java.net/jdk8/docs/technotes/guides/scripting/">Scripting
for the Java Platform</a></li>
<li><a target="_blank"
href="http://download.java.net/jdk8/docs/technotes/guides/scripting/prog_guide/">Java
Scripting Programmer’s guide</a></li>
</ul>
<div class="bottomitem">
<h3>About the Authors</h3>
<div class="row">
<div class="col-sm-12">
<div class="row">
<div class="col-sm-8">
<img class="author-picture"
src="/community/eclipse_newsletter/2014/january/images/DaliborTopic75.jpg"
alt="dalibor topic" />
</div>
<div class="col-sm-16">
<p class="author-name">
Dalibor Topic<br />
<a target="_blank" href="http://www.oracle.com/index.html">Oracle</a>
</p>
<ul class="author-link">
<li><a target="_blank" href="http://robilad.livejournal.com/">Blog</a></li>
<li><a target="_blank" href="https://twitter.com/robilad">Twitter</a></li>
<!--<li><a target="_blank" href="https://plus.google.com/+IanSkerrett">Google +</a></li>
$og-->
</ul>
</div>
</div>
</div>
</div>
</div>
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-34967275-3', 'eclipse.org');
ga('send', 'pageview');
</script>