Slide 1

Slide 1 text

Combining JavaScript and Java
 Polyglot programming on the JVM Ben Ripkens 30 June 2014

Slide 2

Slide 2 text

@BenRipkens • Consulting • Software Development • Trainings

Slide 3

Slide 3 text

Agenda • How not to "share" code • Possible alternatives • Nashorn and JS engine primer • complete Nashorn example • Other ecosystems • Summary

Slide 4

Slide 4 text


 What happens today

Slide 5

Slide 5 text

Web App Mobile App Server Java JavaScript Objective-C Swift

Slide 6

Slide 6 text

Web App Server Java JavaScript

Slide 7

Slide 7 text

That would be great!

Slide 8

Slide 8 text

******** Password Strength weak

Slide 9

Slide 9 text

******** Password Strength great

Slide 10

Slide 10 text

No content

Slide 11

Slide 11 text

Web App Server Java JavaScript function getPwStrength(s) { return 'weak'; } Strength getPwStrength(String s) { return Strength.WEAK; }

Slide 12

Slide 12 text

No content

Slide 13

Slide 13 text

function getPwStrength(s) { return 'weak'; } Strength getPwStrength(String s) { return Strength.WEAK; } SonarQube is happy! Duplications 2.4% 520 lines 28 blocks 20 files

Slide 14

Slide 14 text


 Let's improve on that

Slide 15

Slide 15 text

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; }

Slide 16

Slide 16 text

Possibility 2:
 Domain Specific Languages must contain /a-z/ must contain /A-Z/ must contain /0-9/ should be longer than 6

Slide 17

Slide 17 text

Possibility 3:
 Share code via GWT Java JavaScript

Slide 18

Slide 18 text

Possibility 4:
 JavaScript on the Server Web App Server Java JavaScript function getPwStrength(s) { return 'weak'; } JavaScript

Slide 19

Slide 19 text

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

Slide 20

Slide 20 text

“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

Slide 21

Slide 21 text

https://twitter.com/stilkov/status/313740729577000960

Slide 22

Slide 22 text


 Nashorn Primer

Slide 23

Slide 23 text

Nashorn in a nutshell • JavaScript engine (ECMAScript 5) • part of JDK 8 • JavaScript is compiled to bytecode in memory • replaces Mozilla's Rhino engine

Slide 24

Slide 24 text

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...

Slide 25

Slide 25 text

Syntax and Semantic Event Loop setTimeout Call Stack Task Queue setInterval XMLHttpRequest Math / Date

Slide 26

Slide 26 text

HTML 5 Specification (section 6) ECMAScript XMLHttpRequest Specification Syntax and Semantic Event Loop setTimeout Call Stack Task Queue setInterval XMLHttpRequest Math / Date

Slide 27

Slide 27 text

JavaScript Engine Syntax and Semantic Call Stack Math / Date Memory Management

Slide 28

Slide 28 text

JavaScript Engine Syntax and Semantic Call Stack Math / Date Memory Management

Slide 29

Slide 29 text

• 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

Slide 30

Slide 30 text


 Example
 PW strength check logic

Slide 31

Slide 31 text

http://xkcd.com/936/ Step 1:
 Our PW check shouldn't suck

Slide 32

Slide 32 text

Step 1 (contd.):
 Our PW check shouldn't suck https://tech.dropbox.com/2012/04/zxcvbn-realistic-password-strength-estimation/

Slide 33

Slide 33 text

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

Slide 34

Slide 34 text

Step 2
 Make it work on the server var result = zxcvbn('myPasswordIsRatherLong'); expect(result.score).toBe(2);

Slide 35

Slide 35 text

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 result = (Map) engine.eval(js);

Slide 36

Slide 36 text


 Moving beyond validation

Slide 37

Slide 37 text

• 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

Slide 38

Slide 38 text

• 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

Slide 39

Slide 39 text

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 ]

Slide 40

Slide 40 text

What about the simplification?

Slide 41

Slide 41 text

Web App Server Java JavaScript

Slide 42

Slide 42 text

Web App Mobile App Server Java JavaScript Objective-C Objective-C

Slide 43

Slide 43 text

Objective-C #import ! NSString* js = @"Math.max(2, 3);"; JSContext* context = [[JSContext alloc] init]; JSValue* value = [context evaluateScript:js]; NSLog(@"Max = %d", [value toInt32]);

Slide 44

Slide 44 text

Summary

Slide 45

Slide 45 text

JavaScript is ubiquitous Avatar.js

Slide 46

Slide 46 text

• 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

Slide 47

Slide 47 text

THANKS! @BenRipkens github.com/bripkens/java-with-javascript
 [email protected]
 http://codecentric.de

Slide 48

Slide 48 text

• 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