“ Any application that can be written in JavaScript , will eventually be written in JavaScript” - Jeff Atwood (founder, stackoverflow.com)
In the Beginning - JavaScript Developed by Netscape as a portable version of Java offering a lightweight interpreted language Developed under the name Mocha , officially released as LiveScript in September 1995, Renamed JavaScript in December 1995 as a marketing ploy to leverage off Java's popularity Even reserved Java’s keywords Standardized by ECMA International
JavaScript/Java Timeline 1.3 1.4 5.0 6 7 8 Rhino (Separate download) invokeDynamic Nashorn JDK with Scripting and built in Rhino
Rhino
In the Beginning - Rhino In 1997 Netscape wanted a browser written fully in Java and so it needed an implementation of JavaScript written in Java. Code named " Javagator ", project was canned but engine lived on Compiles JavaScript code to Java bytecodes in either I nterpreted or generated Java class files. Suffers from: Slow compile time M emory leaks Very unsecure!!!
Using Rhino - Command line and REPL jrunscript -e "print('hello world ')“ jrunscript -l js -f helloWorld.js j runscript js > print('Hello World\n '); >>Hello World
Using Scripting API - background “ javax.script ” package Use any JSR-223 compliant scripting language . Java SE 6 & 7 include Scripting API and Mozilla Rhino as default engine Extensive list of available engines: Python, Ruby, PHP, Groovy …
Script API Basics 1) Create a ScriptEngineManager object. ScriptEngineManager factory = new ScriptEngineManager (); 2 ) Get a ScriptEngine object from the manager. ScriptEngine engine = factory.getEngineByName ( "JavaScript" ); 3 ) Evaluate script using the ScriptEngine's eval methods. engine.eval ( "print('Hello, World ')" );
Binding Java objects into script space Bindings bindings = new SimpleBindings (); bindings .put ( "author" , new Person( "Rory" , "Preddy" , 34)); engine .eval ( "print('Name:' + author.name)" , bindings ); >>Name: Rory
Callbacks … engine.put ( " cb " , new JsCallback ()); engine.eval ( " println ('Doing something in javascript here first');" + " cb.apply ('bar');" ); } public void apply(String s){ System. out .println ( "Back in java code here: " + s); } … >>Doing something in javascript here first >>Back in java code here: bar
Implementing Java Interfaces by Scripts String script = "function run() { " + " println ('run called'); " + "}" ; engine.eval (script ); Runnable r = (( Invocable ) engine). getInterface ( Runnable. class ); new Thread(r).start(); >>run called
Java Interfaces in JavaScript var r = new java.lang.Runnable () { run: function () { print( "running...\n" ); } }; var th = new java.lang.Thread (r); th.start (); >>running…
Compiling with Rhino cat test.js java.lang.System.out.println ("hi, mom!"); java org.mozilla.javascript.tools.jsc.Main test.js ls *.class test.class java test >>hi , mom!
Optimization - 1 Interpretive mode is always used. No class files are generated, Basic Compilation . No optimizations are performed. The compiler runs fastest in this mode , but the generated byte code is less efficient 1-9 All optimizations are performed. Java Class Files generated Rhino optimizer not standard with JDK Runtime optimization of compilation can be set from -1 to 9
Nashorn
InvokeDynamic Opcode Usage Invokestatic For static methods Invokevirtual For non-private instance methods Invokespecial For private instance Invokeinterface For the receiver that implements the interface Bytecode operations that were available before JDK version 7:
InvokeStatic
JavaScript is dynamic Things can change at runtime For example, what is the type of: var x = 500000 ; x *= 500000 ; And now? The challenge
Based on an experimental project, the Da Vinci Machine Adds two new concepts to the JVM: invokedynamic bytecode instruction MethodHandle s The first bytecode extension since 1999! Enter JSR 292
InvokeDynamic
Nashorn Default script Engine in Java 8 NO COMILATION ! - Compiles JavaScript directly into byte code 20x faster than uncompiled Rhino Better typing Smaller footprint 100 % compliant with ECMA 5.1 Java 9 has Partial ECMA 6!
> jjs jjs > var x = 10, y = 20; jjs > x + y; >>30 Or > jjs example.js Nashorn- Command Line
Lambdas in Nashorn var list = java.util.Arrays.asList (1, 2, 3, 4, 5, 6, 7, 8); var odd = list.stream ().filter( function (i) { return i % 2 == 0; }); odd.forEach ( function (i) { print( ">>> " + i); }); >>> 2 >>> 4 >>> 6 >>> 8
Nashorn Vs Rhino
Why you care Server-side JavaScript Leverage Existing JavaScript Libraries Cross Platform scripting – Rhino runs on Android Fast performance with Nashorn Leverage some vNode Libraries with Nashorn Why Oracle cares Atwood’s law Node.js A real threat to Java’s server-side growth Let developers handle typing with invokedynamic Jruby , Jython Summary – JavaScript Why bother?