DbSchema
DbSchema

Reputation: 383

Migrate Nashorn to GraalVM

I am using Nashorn JS engine from OpenJDK 12. Nashorn seems to be deprecated. I am looking which are the available alternatives. I found GraalVM, but I am not sure if this is the best. How can I execute a GraalVM JavaScript from Java ? Do you have any example ?

With Nashorn was using from Java:

 NashornScriptEngineFactory nsef = new NashornScriptEngineFactory();
 ScriptEngine engine = nsef.getScriptEngine( BasicDBObject.class.getClassLoader() );
 final Bindings binding = engine.getContext().getBindings(ScriptContext.ENGINE_SCOPE);

In Nashorn I create a WrappedMongoDatabase which extends AbstractJSObject. There I add some 'virtual' methods to simulate the MongoDB Query language, which does for example getCollection('persons').find()... Do you know a way to replace the AbstractJSObject in GraalVM?

I had a look to ProxyObject, somehow I couldn't find a way to override the call(Object thiz, Object... args) like in AbstractJSObject.

public class WrappedMongoDatabase extends AbstractJSObject {

@Override
public boolean hasMember(String name) {
   return "getCollection".equals( name ) || "createCollection".equals(name)||...;
}

@Override
public Object getMember(final String name) {
   if ( hasMember( name ) ){
       return new AbstractJSObject() {
           @Override
            public Object call(Object thiz, Object... args) {
                switch( name ) {
                    case "getCollection":
                            if (args.length == 1 && args[0] instanceof String) {
                                return getCollection((String) args[0]);
                            }
                            break;
                ...
                }
            }   
        }
   }
}
}

Upvotes: 4

Views: 2759

Answers (2)

Xavier D.
Xavier D.

Reputation: 41

GraalVM is a solid way to go. We've been using it for a while now, it runs well, and the JavaScript implementation is far better than Nashorn (or Rhino). In particular, it is ECMA2020 compliant, it supports Node requires (that's huge!), it performs much better, etc...

GraalVM is a big step forward if you're using Nashorn, but it does require some adjustments, which are covered reasonably well in the GraalVM documentation.

Upvotes: 4

Ori Marko
Ori Marko

Reputation: 58822

Follow GraalVM ScriptEngine

ScriptEngine engine = new ScriptEngineManager().getEngineByName("JavaScript");
Bindings bindings = engine.getBindings(ScriptContext.ENGINE_SCOPE);
bindings.put("polyglot.js.allowHostAccess", true);
bindings.put("polyglot.js.allowHostClassLookup", (Predicate<String>) s -> true);
bindings.put("javaObj", new Object());
engine.eval("(javaObj instanceof Java.type('java.lang.Object'));"); // would not work without allowHostAccess and allowHostClassLookup

Notice nashorn compatibility mode:

These options control the sandboxing rules applied to evaluated JavaScript code and are set to false by default, unless the application was started in Nashorn compatibility mode (--js.nashorn-compat=true).

Upvotes: 1

Related Questions