server-side javascript with nashorn and spring

89
Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Server-side JavaScript with Nashorn and Spring By Will Tran & Topher Bullock

Upload: spring-io

Post on 20-Aug-2015

5.363 views

Category:

Software


6 download

TRANSCRIPT

Page 1: Server-side JavaScript with Nashorn and Spring

Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

Server-side JavaScript with Nashorn and Spring

By Will Tran & Topher Bullock

Page 2: Server-side JavaScript with Nashorn and Spring

Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

Intro

Page 3: Server-side JavaScript with Nashorn and Spring

Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

Will Tran• Spring user since 2.5 (2007)• Mainly backend developer• Loves iterating quickly• Hates waiting for server restarts• Lead Java guy on API Gateway for Pivotal CF

Who We Are

Page 4: Server-side JavaScript with Nashorn and Spring

Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

Topher Bullock• Primarily work in JavaScript• Big on Node.js, Chrome & V8, and digging into the workings of

JS Engines• Full-stack development• Leading JavaScript side of API Gateway for Pivotal CF• Based in Toronto on the Pivotal CF Mobile Services team

Who We Are

Page 5: Server-side JavaScript with Nashorn and Spring

Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

Motivation behind this project:• Polyglot Spring• Agile Development• Operation and management consistency

Lessons learned:• Core JavaScript framework on the JVM• Integrating it with Spring Boot and running it on Cloud

Foundry

Raising community awareness and attracting contributors

What This Talk is About

Page 6: Server-side JavaScript with Nashorn and Spring

Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

Motivations

Page 7: Server-side JavaScript with Nashorn and Spring

Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

Polyglot Spring FTW!

http://seduccioncientifica.com/dani/files/2013/02/thump_7408488why-not.jpg

Page 8: Server-side JavaScript with Nashorn and Spring

Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

Faster build, run, test cycles:• Familiar programing model for mobile and web developers• Thriving developer community behind JavaScript• Utilizing existing java modules

Rich management and operations ecosystem:• JVM tools are mature and readily available

Developers, Developers, Developers, Operators!

Page 9: Server-side JavaScript with Nashorn and Spring

Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

Our Primary Use Case

Core technology behind API Gateway for Pivotal CF:• API composition by client developers• Scripting data aggregation, filters and pagination

Page 10: Server-side JavaScript with Nashorn and Spring

Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

Netflix API Redesign Case Study

http://techblog.netflix.com/2012/07/embracing-differences-inside-netflix.html

Page 11: Server-side JavaScript with Nashorn and Spring

Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

Resource / User APIs

Cross-platform Client Issues

Netflix Android app

LocalizationAPIs

Media / Content APIs

Page 12: Server-side JavaScript with Nashorn and Spring

Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

Netflix API Redesign

http://techblog.netflix.com/2012/07/embracing-differences-inside-netflix.html

Page 13: Server-side JavaScript with Nashorn and Spring

Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

“Embrace the Differences of the Devices”

http://techblog.netflix.com/2012/07/embracing-differences-inside-netflix.html

Page 14: Server-side JavaScript with Nashorn and Spring

Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

Why JavaScript?

Page 15: Server-side JavaScript with Nashorn and Spring

Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

Nashorn

Page 16: Server-side JavaScript with Nashorn and Spring

Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

JIFASNIF!JavaScript is Fun and So Node.js Nashorn is Fun!

Page 17: Server-side JavaScript with Nashorn and Spring

Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

Nashorn : The Tip of the Horn

•Released with Java 8, uses new hotness from Java 8 (functional interfaces)•Based on the Da Vinci Machine (JSR 292) & leverages newer JVM (invokedynamic / MethodHandle) features•Lots of work being done by Oracle to create a modern JavaScript engine for the JVM

More in-depth discussion on Nashorn later!

Page 18: Server-side JavaScript with Nashorn and Spring

Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

• Nashorn can easily import (and extend) Java classes / types and write JS on top of them

• Scripting languages are relatively simple to pick up and JS devs can comfortably write code that runs in the JVM

• When your message format is JSON; JavaScript makes a lot of sense

• There are already great patterns for ADT manipulation in JS (Lo-Dash) and asynchronous code (Promises A+)

Polyglot JVM

Page 19: Server-side JavaScript with Nashorn and Spring

Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

• Embedded ScriptEngine lets you quickly script behavior• JVM & Nashorn allows hotswapped JavaScript code, which can

be altered at runtime

Dynamic Scriptability : ( AKA : WE’LL DO IT LIVE! )

William Tran
OMG I just saw the Bill Oriely video.
Page 20: Server-side JavaScript with Nashorn and Spring

Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

JS Runtime Use Cases

• Great for runtime configuration of apps• Rapid, high-velocity, agile development• Exploratory programming and kicking the tires on an application

is very simple in JS

Page 21: Server-side JavaScript with Nashorn and Spring

Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

“Velocity on the JVM is the Killer App”- SpringOne 2GX 2014 Keynote

.. literally 3 days ago

Page 22: Server-side JavaScript with Nashorn and Spring

Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

•ScriptEngine is a ‘sandbox’ you have full control over•Nashorn’s Global scope is a blank slate; •You can expose domain-specific Java classes or JavaScript libraries to developers working in JavaScript.

You Control the JS Environment

*any resemblance to actual JS devs is purely coincidental

*

Page 23: Server-side JavaScript with Nashorn and Spring

Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

Page 24: Server-side JavaScript with Nashorn and Spring

Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

API Gateway : Tweetable App

JS with domain specific libraries lets you write very terse applications and iterate on them quickly.

var Router = require("Router"), app = new Router();app.get(“/”, function( req, res) { res.setBody({ “hello” : "world" });});module.exports = app;

Page 25: Server-side JavaScript with Nashorn and Spring

Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

Recap

•Strong use case for opening up our Spring / Java applications to scripting languages•Dynamic scripting languages can allow more rapid iteration and higher velocity development, as well as runtime configuration post-build•JavaScript is fun!•Java still controls how much ‘fun’, and can expose domain specific libraries to assist in certain tasks

Page 26: Server-side JavaScript with Nashorn and Spring

Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

Framework Requirements

Page 27: Server-side JavaScript with Nashorn and Spring

Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

Goals:• For parallel execution and aggregation• Hide the details of multithreading from the developer• Make asynchronous flows manageable

• Avoid callback hell

Solution:• Implement Promises (Promise / A+)

Asynchronous JavaScript

Page 28: Server-side JavaScript with Nashorn and Spring

Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

Goals:• Minimize the number of ScriptEngine instances we need• Maximize CPU utilization and throughput

Solution:• Apache’s HttpAsyncClient• Redisson Redis client (fork of Lettuce, uses Netty)• ThreadPoolTaskExecutor for existing blocking I/O libraries

• JDBC is a synchronous API

Non-blocking JavaScript and I/O

Page 29: Server-side JavaScript with Nashorn and Spring

Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

Goals:• Iterate without restarting the server• Enable exploratory programming• Get stuff done quickly• Just hit F5 (or Cmd Shift R)

Solution:• Updatable JavaScript module cache

Runtime Editable JavaScript

Page 30: Server-side JavaScript with Nashorn and Spring

Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

Goals:• TDD should be just as painless• Add and update tests without restarting

Solution:• Behaviour driven testing with Jasmine• Option to enable the test framework on the running server• Integration with JUnit / Maven Surefire / CI

Runtime Testable JavaScript

Page 31: Server-side JavaScript with Nashorn and Spring

Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

Goals:• Curate a selection of libraries that make sense in our use case• Be able to use these libraries without modification

Solution:• lodash, handlebars, json-mask available on classpath

• var _ = require(‘lodash’);

Compatibility with open source JS libraries

Page 32: Server-side JavaScript with Nashorn and Spring

Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

Goals:• Take advantage of all the great stuff in Spring• Take advantage of existing Java assets

Solution:• use Spring as the bridge between Java application components

and JavaScript• Expose ApplicationContext to the JS application

Ease of integration with Spring

Page 33: Server-side JavaScript with Nashorn and Spring

Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

Recap: What We Want, What We Really Really Want

•Asynchronous JavaScript•Non-blocking JavaScript and I/O•Runtime Editable JavaScript•Runtime Testable JavaScript•JS Library Compatability•Integration with Spring in our JS runtime

Page 34: Server-side JavaScript with Nashorn and Spring

Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

Demo

Page 35: Server-side JavaScript with Nashorn and Spring

Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

Performance

Page 36: Server-side JavaScript with Nashorn and Spring

Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

Test Setup

m1.largedatasource

m1.largeapp server

m3.xlargeJMeter

EC2

9kBJSON(gzip)

9kBJSON

Page 37: Server-side JavaScript with Nashorn and Spring

Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

Page 38: Server-side JavaScript with Nashorn and Spring

Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

Page 39: Server-side JavaScript with Nashorn and Spring

Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

The Gory Details

Page 40: Server-side JavaScript with Nashorn and Spring

Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

A Brief Nashorn Overview

Page 41: Server-side JavaScript with Nashorn and Spring

Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

• Nashorn 99.9% EMCA test262 compliant vs Rhino’s is 95%• Rhino performance issues; Memory Leaks / Filling PermGen

when running in compiled mode. • Nashorn’s code base is a new engine from the ground-up, and is

cleaner than Rhino’s old code base.

Rhino vs Nashorn

Page 42: Server-side JavaScript with Nashorn and Spring

Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

Esprima parsing performance

http://ariya.ofilabs.com/2014/03/nashorn-the-new-rhino-on-the-block.html

Page 43: Server-side JavaScript with Nashorn and Spring

Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

•Uses invokedynamic to implement all of its invocations.•Attempts to bind calls to appropriate Java methods instead of less performant JavaScript functions.•Runtime linker library assists the binding of invokedynamic calls using the java.lang.invoke API; manages a history of calls, so that lookup is faster on successive relinks.

Nashorn is Fancy!

Page 44: Server-side JavaScript with Nashorn and Spring

Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

//get Nashorn ScriptEngine instance from ScriptEngineManager

ScriptEngineManage manager = new ScriptEngineManager();

manager.getEngineByName("nashorn");

//retrieve engine context

ScriptContext defCtx = engine.getContext();

// add 'foo' var to global scope

defCtx.getBindings(ScriptContext.GLOBAL_SCOPE).put("foo", "hello");

// or engine.put(“foo”, “hello”);

engine.eval("print(foo)"); // prints 'hello'

Nashorn Context Customization

Page 45: Server-side JavaScript with Nashorn and Spring

Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

Nashorn Context Customization

// ... get Nashorn ScriptEngine instance from ScriptEngineManager

//create a new Simple Script ContextScriptContext myCtx = new SimpleScriptContext();//create a new Bindings object (basically a hash of var => value)Bindings b = new SimpleBindings();b.put("foo", "world"); //set bindings on your context and apply them to the Global ScopemyCtx.setBindings(b, ScriptContext.GLOBAL_SCOPE); engine.eval("print(foo)", myCtx); // prints "world"

Page 46: Server-side JavaScript with Nashorn and Spring

Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

Rhino occasionally exhibits strange behaviors when calling overloaded methods on Java Classes, while Nashorn seems to do much better at inferring type from args.

This lead to writing a lot of wrapper ScriptableObject classes for Rhino, using @JSConstructor and @JSFunction annotations

...

Rhino vs Nashorn : Accessing Java Classes

Page 47: Server-side JavaScript with Nashorn and Spring

Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

Spring to Nashorn Bridge

Page 48: Server-side JavaScript with Nashorn and Spring

Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

@Resourceprivate ApplicationContext context;

//...//…

ScriptEngineManager engineManager = new ScriptEngineManager();ScriptEngine scriptEngine = engineManager.getEngineByName("nashorn"); scriptEngine.put("spring", context);

Spring to Nashorn Bridge

Nashorn lets us easily add the Spring context into its Global Scope:

Page 49: Server-side JavaScript with Nashorn and Spring

Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

Spring to Nashorn Bridge

var fooServiceByName = spring.getBean("fooService");

var fooServiceByClass =

spring.getBean(Java.type("com.example.FooService"));

var fooServiceByNameAndClass =

spring.getBean("fooService",Java.type("com.example.FooService"));

This lets us access Spring beans from our JavaScript code:

Page 50: Server-side JavaScript with Nashorn and Spring

Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

Spring Boot Features

Page 51: Server-side JavaScript with Nashorn and Spring

Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

“Spring Boot makes Spring development fun again”

- Monday keynote

• It also makes it really easy to build your own framework that’s fun to use

A framework for frameworks

Page 52: Server-side JavaScript with Nashorn and Spring

Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

Embedded container• Use embedded Tomcat or Jetty to run your application• Idiotproofs your IDE setup (or lack thereof)• Your application is fully self-contained

• All you need is Java• Easier to manage differences between

dev/staging/production • Developer Productivity• Ease of deployment

Spring Boot Features

Page 53: Server-side JavaScript with Nashorn and Spring

Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

Autoconfiguration• provides a default configuration for a set of interdependent

components, when appropriate• the presence of a class in the classpath

@ConditionalOnClass({ Redisson.class })• the absence of a user-defined bean

@ConditionalOnMissingBean• Config Classes / methods with these annotations are evaluated

after those that don’t have @Conditional annotations

Spring Boot Features

Page 54: Server-side JavaScript with Nashorn and Spring

Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

Spring Cloud Connectors and Cloud Foundry• ServiceInfoCreators

• parses CF environment variables into ServiceInfo objects that describe how to connect to services (eg Redis)

• ServiceConnectorCreators• Use a ServiceInfo object to create application components

(eg Redisson client)• Uses the Java ServiceLoader pattern

(classpath:/META-INF/services) to define services

Spring Boot Features

Page 55: Server-side JavaScript with Nashorn and Spring

Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

Externalized Configuration• application.properties

• Properties can be overridden at start time• default properties bundled with the jar on classpath• environment specific properties loaded from filesystem

• Our needs• default properties on classpath in the core dependency• override defaults in the dependent projects

• Problem• default properties in the core dependency were shadowed

by dependent projects

Spring Boot Features

Page 56: Server-side JavaScript with Nashorn and Spring

Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

Externalized Configuration• Example

• Core project: classpath:/application.properties• Dependent project: classpath:/application.properties• When assembled, Only the Dependent project’s

application.properties is used• Solution

• rename the core property file and rejig spring.config.locations

• Example

Spring Boot Features

Page 57: Server-side JavaScript with Nashorn and Spring

Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

Customizable banner• classpath:/banner.txt• Flex your ASCII art skillz

Spring Boot Features

___ ___ ___ ___ ___ / /\ / /\ / /\ ___ /__/\ / /\ / /:/_ / /::\ / /::\ / /\ \ \:\ / /:/_ / /:/ /\ / /:/\:\ / /:/\:\ / /:/ \ \:\ / /:/ /\ / /:/ /::\ / /:/~/:/ / /:/~/:/ /__/::\ _____\__\:\ / /:/_/::\ /__/:/ /:/\:\ /__/:/ /:/ /__/:/ /:/___ \__\/\:\__ /__/::::::::\ /__/:/__\/\:\ \ \:\/:/~/:/ \ \:\/:/ \ \:\/:::::/ \ \:\/\ \ \:\~~\~~\/ \ \:\ /~~/:/ \ \::/ /:/ \ \::/ \ \::/~~~~ \__\::/ \ \:\ ~~~ \ \:\ /:/ \__\/ /:/ \ \:\ \ \:\ /__/:/ \ \:\ \ \:\/:/ /__/:/ \ \:\ \ \:\ \__\/ \ \:\ \ \::/ \__\/ \__\/ \__\/ \__\/ \__\/ ___ ___ _____ / /\ / /\ ___ / /::\ / /::\ / /::\ / /\ / /:/\:\ / /:/\:\ / /:/\:\ / /:/ / /:/~/::\ / /:/ \:\ / /:/ \:\ / /:/ /__/:/ /:/\:| /__/:/ \__\:\ /__/:/ \__\:\ / /::\ \ \:\/:/~/:/ \ \:\ / /:/ \ \:\ / /:/ /__/:/\:\ \ \::/ /:/ \ \:\ /:/ \ \:\ /:/ \__\/ \:\ \ \:\/:/ \ \:\/:/ \ \:\/:/ \ \:\ \ \::/ \ \::/ \ \::/ \__\/ \__\/ \__\/ \__\/

Topher Bullock
nice!
Page 58: Server-side JavaScript with Nashorn and Spring

Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

Module Loader

Page 59: Server-side JavaScript with Nashorn and Spring

Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

Node-style CommonJS Module Loader

Goals• CommonJS Module Loader which functions similar to

Node.js• Ability to have some drop-in support for other CommonJS

modules from bower & npm*

* Browser & Node.js Core APIs aren’t supported currently

Page 60: Server-side JavaScript with Nashorn and Spring

Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

CommonJS Module Spec - Overview

•require is a function global scope that accepts a module identifier (path, or name) and returns the exported API of a foreign module•In a module, there is a free variable exports, that is an object that the module may add its API to as it executes.•Module identifiers may be "relative" or "top-level" •Relative identifiers are resolved relative to the identifier of the module in which require is written and called.

Page 61: Server-side JavaScript with Nashorn and Spring

Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

CommonJS Example

var math = require('../libs/math.js');

exports.addArrays(op1, op2){

return math.add(op1[0],op1[1]) + math.add(op2[0],op2[1]);

}

exports.add = function(x,y) {

return x+y;

};

math.js

calculator.js

Page 62: Server-side JavaScript with Nashorn and Spring

Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

CommonJS Style Module Loader

•Every script engine instance is instantiated with our require function in its Global Scope•They share a ConcurrentHashMap of JS source keyed by path •Module APIs returned from module.exports are cached in a JavaScript object

Page 63: Server-side JavaScript with Nashorn and Spring

Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

CommonJS Style Module Loader

•Module content can be hot-swapped at runtime; from file system or Redis•Evaluates content of JS files so that code can be run in its own closure and module.exports can be returned.•Modules are ‘decorated’ to include details about the file being evaluated, since we are eval() -ing anonymous blocks of JS code

Page 64: Server-side JavaScript with Nashorn and Spring

Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

Java / JS object interoperability

Page 65: Server-side JavaScript with Nashorn and Spring

Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

[“this”, “is”, “definitely”, “not”, “a”, ”Collection”]• JS arrays are not compatible with java.util.Collection

• Need to use java.util.Arrays.asList()• They are compatible with Java arrays

• Nashorn will copy to/from Java array and box/unbox/convert types as needed

Java / JS object interoperability

Page 66: Server-side JavaScript with Nashorn and Spring

Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

{this: “is”, not: “quite”, a, “HashMap”}• java.util.Map can be accessed in the same way as a JS Object

• map.foo=bar, map[‘foo’] = bar• It’s still not a JS Object

• cannot do Object.keys(map)• When needed, JS Objects are wrapped as ScriptObjectMirror

which implements java.util.Map

Java / JS object interoperability

Page 67: Server-side JavaScript with Nashorn and Spring

Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

JS Functions -> Java Lambda• Java methods that can accept a lambda can be called with a JS

function from within Nashorn• Collection stream api roughly equivalent to lodash

Java / JS object interoperability

Page 68: Server-side JavaScript with Nashorn and Spring

Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

Multithreaded JavaScript

Page 69: Server-side JavaScript with Nashorn and Spring

Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

JavaScript is single threaded

"ECMAScript 5.1 language specification doesn't define multithreading semantics for programs written in the language; they are inherently single threaded. If we were to make them thread safe, we'd be sacrificing single threaded performance for a behaviour that falls outside of the specification."

- Attila Szegedi, Nashorn lead, July 2013

Multithreaded JavaScript

Page 70: Server-side JavaScript with Nashorn and Spring

Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

JavaScript is asynchronous• Singlethreaded and asynchronous…? Event loop• How do we write asynchronous code?

CPUs are multi-core• How do we utilize all cores for executing JS?

Multithreaded JavaScript

Page 71: Server-side JavaScript with Nashorn and Spring

Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

How do we write asynchronous code?• Callbacks

Multithreaded JavaScript

Page 72: Server-side JavaScript with Nashorn and Spring

Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

How do we write asynchronous code?• Promises (Promise A+)

Multithreaded JavaScript

Page 73: Server-side JavaScript with Nashorn and Spring

Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

How do we implement multithreaded Promises?• Spawn a new thread, run it, toss it

• This creates a new Global, need to re-load all the JS• ScriptEngine (and the application loaded by it) is expensive

to create• ScriptEngine object pooling

• Nashorn’s Global is stored in a ThreadLocal• ScriptEngine is not fully self-contained• It can’t be passed around and used by whatever thread

whenever its needed

Multithreaded JavaScript

Page 74: Server-side JavaScript with Nashorn and Spring

Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

How do we implement multithreaded Promises?• ScriptEngines in a fixed size threadpool

• Use ThreadPoolExecutor• corePoolSize == maxPoolSize ==

Runtime.getRuntime().availableProcessors()• Have the executor threads create a the script engine and

store the ScriptEngine in a ThreadLocal for reuse• The Global and corresponding ScriptEngine will always be

used by the thread that created it and nobody else

Multithreaded JavaScript

Page 75: Server-side JavaScript with Nashorn and Spring

Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

Java Futures to JavaScript Promises• Futures

• “A Future represents the result of an asynchronous computation”

• Returned by java.util.concurrent.ThreadPoolExecutor• Future.get() will block until the result is available

• Promises• “A promise represents the eventual result of an

asynchronous operation.”

Multithreaded JavaScript

Page 76: Server-side JavaScript with Nashorn and Spring

Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

Java Futures to JavaScript Promises• Promises

• “A promise represents the eventual result of an asynchronous operation.

• “The primary way of interacting with a promise is through its then method, which registers callbacks to receive either a promise’s eventual value or the reason why the promise cannot be fulfilled.”

Multithreaded JavaScript

Page 77: Server-side JavaScript with Nashorn and Spring

Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

Java Futures to JavaScript Promises• Future Problems

• No facility for registering callbacks• We never want to block on Future.get() from within the

ScriptEngine• Promise Solution

• Blocking had to be done outside ScriptEngine• Promises written in Java, decorates Future• Blocking done using a different ThreadPoolExecutor

Multithreaded JavaScript

Page 78: Server-side JavaScript with Nashorn and Spring

Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

ScriptObject vs ScriptObjectMirror• How do we pass around the results of these Promises to

different ScriptEngines?• We need to understand the differences• ScriptEngine.eval can return:

• a Java Objecto se.eval(“somePojo.someJavaObject();”);

• a ScriptObjectMirroro se.eval(“{hello: ‘world’};”);

Multithreaded JavaScript

Page 79: Server-side JavaScript with Nashorn and Spring

Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

ScriptObject vs ScriptObjectMirror• Internally, JS objects in Nashorn are ScriptObjects• When returning JS objects to Java, Nashorn wraps

ScriptObjects with ScriptObjectMirror to allow it to be usable outside of the ScriptEngine• ScriptObjectMirror = ScriptObject + Global it came from

Multithreaded JavaScript

Page 80: Server-side JavaScript with Nashorn and Spring

Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

ScriptObject vs ScriptObjectMirror

Multithreaded JavaScript

• Globals Colliding!• During testing, we found that we were unable to pass

ScriptObjectMirrors around to different ScriptEngines for manipulation

Page 81: Server-side JavaScript with Nashorn and Spring

Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

ScriptObject vs ScriptObjectMirror• Solution: Prevent ScriptObjectMirror from wrapping

ScriptObjects• In the ScriptEngine, wrap the result in a POJO• Out of the ScriptEngine, unwrap the POJO

• ScriptObject can now be passed directly into other ScriptEngines

Multithreaded JavaScript

Page 82: Server-side JavaScript with Nashorn and Spring

Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

JSON.parse / JSON.stringify

Page 83: Server-side JavaScript with Nashorn and Spring

Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

Problems with Nashorn’s JSON• JSON.stringify cannot deal with POJOs

• By design• We wanted more seamless interoperability with Java• JSON.parse is slower

JSON.parse / JSON.stringify

Page 84: Server-side JavaScript with Nashorn and Spring

Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

Jackson to the rescue!• We’ve replaced the global JSON with our own that uses

Jackson• parses to Map / List, then deep converts to ScriptObject• ScriptObjectSerializer Jackson Module

JSON.parse / JSON.stringify

Page 85: Server-side JavaScript with Nashorn and Spring

Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

Jackson vs Nashorn• benchmarks (JMH Microbenchmarks on my Macbook Pro)

• [{"date":"2014-06-18T15:08:36.024Z", "integer":1, "float":1.01, "boolean":true, "obj":{"str":"foobar"}, "arr":[true,false,null,null]}]

o Jackson vs Nashorn parse 120000 ops/s vs 88000 ops/so Jackson vs Nashorn stringify 105000 ops/s vs 86000

ops/s

JSON.parse / JSON.stringify

Page 86: Server-side JavaScript with Nashorn and Spring

Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

Jackson vs Nashorn• benchmarks cont’d

• large JSON (38400 bytes, 1920 arrays of integers, max depth 47)o Jackson vs Nashorn parse 926 ops/s vs 489 ops/so Jackson vs Nashorn stringify 337 ops/s vs 535 ops/s

• Nashorn is better at stringifying large, deeply nested objects

JSON.parse / JSON.stringify

Page 87: Server-side JavaScript with Nashorn and Spring

Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

The Future[is bright!]

Page 88: Server-side JavaScript with Nashorn and Spring

Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

Better Async internals:• Use ListenableFuture instead of Future• Use Reactor• Use Netty instead of an embedded servlet container

NPM package management support

More strict CommonJS Module Spec Compliance

Open Source

What’s Next

Page 89: Server-side JavaScript with Nashorn and Spring

Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

Topher Bullock• Twitter @topherbullock• Email [email protected]

Will Tran• Twitter @fivetenwill• Email [email protected]

That’s All Folks!