Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Polyglot programming on the JVM

Sponsored · Your Podcast. Everywhere. Effortlessly. Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.

Polyglot programming on the JVM

How do you share code between client (JavaScript) and the server (Java)? An overview over Java 8 and project Nashorn.

This presentation was given at enterJS 2014 (2014-05-30).

Avatar for Ben Ripkens

Ben Ripkens

June 30, 2014
Tweet

More Decks by Ben Ripkens

Other Decks in Programming

Transcript

  1. Agenda • How not to "share" code • Possible alternatives

    • Nashorn and JS engine primer • complete Nashorn example • Other ecosystems • Summary
  2. Web App Server Java JavaScript function getPwStrength(s) { return 'weak';

    } Strength getPwStrength(String s) { return Strength.WEAK; }
  3. function getPwStrength(s) { return 'weak'; } Strength getPwStrength(String s) {

    return Strength.WEAK; } SonarQube is happy! Duplications 2.4% 520 lines 28 blocks 20 files
  4. Possibility 1:
 Logic only on the server-side Web App Server

    Java JavaScript function getPwStrength(s) { var url = '/pwstrength?pw=' + encodeURIComponent(s); return $.get(url); } @GET @Path("/pwstrength") @Produces("application/json") Strength getPwStrength( @QueryParam("pw") String pw) { return Strength.WEAK; }
  5. Possibility 2:
 Domain Specific Languages must contain /a-z/ must contain

    /A-Z/ must contain /0-9/ should be longer than 6
  6. Possibility 4:
 JavaScript on the Server Web App Server Java

    JavaScript function getPwStrength(s) { return 'weak'; } JavaScript
  7. How is this better than GWT? • Java is not

    a native language of the web • GWT compiles Java to another language • GWT needs to include many standard libraries in order to make the magic work • GWT needs complex build steps
  8. “GWT is a reasonable implementation of a poor architectural choice.

    [...] First, in many ways, JavaScript is more powerful and expressive than Java, so we suspect that the generation is going in the wrong direction. [...]” ! ThoughtWorks Technology Radar July 2011 http://www.thoughtworks.com/radar/#/platforms/gwt
  9. Nashorn in a nutshell • JavaScript engine (ECMAScript 5) •

    part of JDK 8 • JavaScript is compiled to bytecode in memory • replaces Mozilla's Rhino engine
  10. Hello World ScriptEngineManager manager = new ScriptEngineManager(); ScriptEngine engine =

    manager.getEngineByName("nashorn"); String js = "print('Hello World!');" engine.eval(js); Unfortunately there is a small issue...
  11. HTML 5 Specification (section 6) ECMAScript XMLHttpRequest Specification Syntax and

    Semantic Event Loop setTimeout Call Stack Task Queue setInterval XMLHttpRequest Math / Date
  12. • It is possible to import and use Java classes

    • this provides the ability to build your own event loop • some awesome people have already done this, but it needs to be improved: ! • if you only need the event loop: Simulating Browser APIs https://gist.github.com/bripkens/8597903 https://bugs.openjdk.java.net/browse/JDK-8006183
  13. Step 1 (contd.):
 Our PW check shouldn't suck bower install

    --save dropbox/zxcvbn#v1.0 Remember this dependency Install from GitHub dropbox/zxcvbn repository the tag v1.0 Save dependency to local disc
  14. Step 2
 Make it work on the server var result

    = zxcvbn('myPasswordIsRatherLong'); expect(result.score).toBe(2);
  15. assertThat(result.get("score"), is(2)); Step 2 (contd.):
 Make it work on the

    server ScriptEngineManager manager = new ScriptEngineManager(); ScriptEngine engine = manager.getEngineByName("nashorn"); Bindings globalScope = engine.getBindings(ScriptContext.ENGINE_SCOPE); globalScope.put("window", globalScope); engine.eval(slurp("/bower_components/zxcvbn/zxcvbn.js")); String js = "zxcvbn('myPasswordIsRatherLong');";
 Map<String, Object> result = (Map<String, Object>) engine.eval(js);
  16. • Generate hints for the user based on data that

    has been loaded • use the same template engine on client and server • compile LESS CSS on the server What you might want to do
  17. • basically Node.js on the JVM with the help of

    Nashorn • enables you to do require('events') and more • uses libuv to support Node.js APIs • unfortunately still very young and not well documented Avatar.js to the rescue
  18. Node.js modules Run with Avatar.js on the JVM Transpile with

    browserify Run in the browser [ browser ] [ JVM ] Run on Node.js [ Node.js ]
  19. Objective-C #import <JavaScriptCore/JavaScriptCore.h> ! NSString* js = @"Math.max(2, 3);"; JSContext*

    context = [[JSContext alloc] init]; JSValue* value = [context evaluateScript:js]; NSLog(@"Max = %d", [value toInt32]);
  20. • Share not only business, but also UI logic •

    Offline-first becomes more and more viable • run Node.js modules as part of your Maven based build process • we will probably come up with some very interesting use cases Summary
  21. • On password strength estimation • http://xkcd.com/936/ • https://tech.dropbox.com/2012/04/zxcvbn-realistic-password-strength- estimation/

    • http://www.troyhunt.com/2014/05/the-ebay-breach-answers-to-questions.html • Specifications • http://www.ecma-international.org/ecma-262/5.1/ • http://www.w3.org/TR/html5/webappapis.html#timers • http://www.w3.org/TR/XMLHttpRequest/ • Misc • https://avatar-js.java.net/ • http://alistapart.com/article/offline-first References