More than just Node.js
on the Java Virtual Machine

Niko Köbler (@dasniko)

I'm to Hire!



(undefined is not a function!)

With Java, We Have...

  • Longterm investments
  • Mature solutions
  • Complex and extensive business logic
  • Integration of heterogeneous environments
    across platforms
  • Blueprints and best-practices available
  • Proven infrastructure

And now,
you tell us about this
Brave New (Node-)World

  • Mostly new applications
  • Mostly No-SQL backed
  • New application approaches
  • More focused silo apps
  • "Cool stuff"
  • > 110.000 NPM libraries available
  • No enterprise integration (yet)
  • Infrastructure?

Speaking JavaScript

Like it or not, JavaScript is everywhere these days - from browser to server to mobile - and now you, too, need to learn the language or dive deeper than you have.
Dr. Axel Rauschmayer


I think JavaScript has been seen as a serious language for the last two or three years; I think now increasingly we’re seeing JavaScript as a platform.
(Sam Newman, ThoughtWorks’ Global Innovation Lead)

JavaScript has emerged both as a platform for server-side code but also a platform to host other languages.
(January, 2014)




  • JavaScript Enginge on the JVM
  • based on invokedynamic feature
  • competes with Google V8
  • ECMAScript 5.1 compatible (ECMAScript 6 in future)
  • Seamless interoperability of Java and JavaScript
  • Language and API Extensions closures, collections & for each, multi-line string literals, string interpolation, __noSuchProperty__, __noSuchMethod__, typed arrays, binding properties, error extensions, conditional catch clause, String functions, and many, many more...

Java & JavaScript

...are similar than car and carpet are similar.


Command line client

$ $JAVA_HOME/bin/jjs
jjs> print('Hello Nashorn!');

Invoking JavaScript from Java

ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
engine.eval("print('Hello Nashorn!');");
engine.eval(new FileReader("scriptfile.js"));
Invocable invocable = (Invocable) engine;
Object result = invocable.invokeFunction("jsSayHello", "Nashorn");


Invoking Java from JavaScript

package my.package;
public class MyJavaClass {
    static String sayHello(String name) {
        return String.format("Hello %s from Java!", name);
var MyJavaClass = Java.type('my.package.MyJavaClass');
var result = MyJavaClass.sayHello('Nashorn');
print(result); // Hello Nashorn from Java!


Node.js on the JVM

~95% Node.js API compatibility
no Chrome V8 native APIs
many of the node-modules work
(e.g.: abbrev, ansi, async, block-stream, chmodr, chownr, coffee-script, colors, commander, connect, debug, engine.io, express, ftsream, glob, graceful-fs, inherits, ini, init-package-json, grunt, grunt-bower-task, jade, lodash, mime, mkdirp, mocha, moment, mongodb, mongoose, mustache, node-unit, node-uuid, once, opener, optimist, osenv, passport, q, read, redis, request, retry, rimraf, ronn, semver, slide, socket.io, tar, uglify-js, uid-number, underscore, which, winston)


Project Avatar

  • End-to-end fullstack framework
    • Client-Library
    • Services (REST, WS, SSE)
    • JMS
  • Running in a Java EE Application Server
    • Glassfish 4
    • WebLogic 12.1.3

Avatar-JS &
Project Avatar

Avatar 2.0

Avatar 2.0

  • no more Java EE application server needed
  • single, standalone JVM

Threads &



Message Bus

var avatar = require('org/glassfish/avatar');
var threads = require('org/glassfish/avatar/threads');
var app = avatar.application;
var name = app.name;
var bus = app.bus;
// listen for messages on topic 'hello'
bus.on('hello', function(body, msg) {
    print(name + ' got message: ' + JSON.stringify(body));
// publishing to 'hello' topic (e.g. in file hello.js):
bus.publish('hello', { x : 'x', y : 'y' });
// start a background thread for publishing
threads.newBackgroundThread('background', 'hello.js').start();

Message Bus Methods

bus.publish(topic, body);
bus.publishTo(address, topic, body);
bus.send(topic, body);
bus.sendTo(address, topic, body);
bus.reply(replyTo, body); 

Shared State

Cache/Map API: Key-Value-Store
(Coherence backed, Cache/JSR-107 compliant)
var avatar = require('org/glassfish/avatar');
var state = avatar.application.state;

state.put('key', {'value': 'myValue'});

state.keys(); // -> Array
state.contains('key'); // -> boolean
state.get('key'); // -> Object
state.remove('key'); // -> void

Avatar Persistence


Model-Store API

database setup

var store = avatar.newStore(‘mysql’, {
    host: 'localhost',
    port: 3306,
    database: 'test',
    username: 'root',
    createDb: true
  • JPA (Eclipselink) / JDBC based
  • relational and non-relational
  • user-transactions possible

Model-Store API

model setup
var Family = avatar.newModel('family', {
        "name" : {
            type : "string",
            primary : true
        "description" : "string"
var Product = avatar.newModel('product', {
        "name" : {
            type : "string",
            primary : true
        "madeBy" : "string",
        "price" : "number",
        "quantity" : "integer"

Model-Store API

relations & binding
Family.hasMany(Product, {
    as : 'products',
    foreign : 'family'
store.bind(Family, Product);

Model-Store API

usage during runtime
store.connect(function() {
        name: 'Widget',
        price: 1.00,
        quantity: 2,
    }, function(err, w1) {
        store.disconnect(function() {
            // done


  • UI Library
  • REST Services
  • (Web-)Socket Services
  • Push Services (SSE)
  • JMS


--> new t3 thin client
for JMS & remote EJB calls

Demo Time

Competitors ?

--> Java Magazin 03/2015

Avatar 2.0 - Conclusion

  • Lightweight Node.js integration in Java Enterprise context
  • Run JavaScript Apps on a standard Java Infrastructure
    • 95% Node.js API compatibility
  • Multi-threaded, asynchronous, non-blocking API
  • Run one event-loop per thread,
    multiple threads
  • Inter-Thread-communication /
    shared state via event bus or map API
  • Avatar Persistence (Model-Store-API)
  • http://avatar.java.net

Avatar 2.0

Thank you!


Made with Slides.com