Extending classes in global scope
Denero Watz
denerowatz at gmail.com
Thu Aug 22 04:59:38 UTC 2019
Sorry if this is not the right list to ask this, I couldn't find any other
mailing list for posting issues in Nashorn.
We have a web application written in GWT that also provides a set of
scripting APIs.
The requirement is to support the same set of APIs on server. So rather
than rewriting this, we plan to use the GWT code in Nashorn.
We tried that but found it is slow compared to the client side browser. So
our server team has come up with an idea to load this library in global
scope and have the user defined scripts run in engine scopes. That way, the
GWT module can be loaded only once. But we have hit a problem that
extending classes in the global scopes doesn't work. On further
investigation it is found that it is nothing to do with GWT and can be
reproduced with the following standalone code also.
// -------------------- TESTCODE: START-------------------------- //
NashornScriptEngineFactory nashornEngineFactory = new
NashornScriptEngineFactory();
SimpleScriptContext context = new SimpleScriptContext();
ScriptEngine scriptEngine = nashornEngineFactory.getScriptEngine(new
String[]{"--optimistic-types=false"});
Bindings gBindings = scriptEngine.createBindings();
context.setBindings(gBindings, ScriptContext.GLOBAL_SCOPE);
Bindings bindings = scriptEngine.createBindings();
context.setBindings(bindings, ScriptContext.ENGINE_SCOPE);
scriptEngine.eval(
"function MyBaseClass(name, level) {this.name = name; this.level =
level;} MyBaseClass.prototype.greet = function() { return this.name+ ' says
hello.'};",
gBindings/* context */); // ---------->(1)
scriptEngine.eval("var extendClass = function(baseClass, subClass) {" +
"function proxy() {};" +
"proxy.prototype = baseClass.prototype;" +
"subClass.prototype = new proxy();" +
"subClass.prototype.constructor = subClass;" +
"subClass.baseConstructor = baseClass;" +
"subClass.superClass = baseClass.prototype;" +
"};", context);
scriptEngine.eval("var MySubClass = function(name, level) {this.name =
name; this.level = level;};", context);
scriptEngine.eval("extendClass(MyBaseClass, MySubClass);", context);
scriptEngine.eval("var mytest = new MySubClass('test1', 2);", context);
scriptEngine.eval("print('mytest: ' + mytest.greet());", context);
// -------------------- TESTCODE: END-------------------------- //
The last statement in this code fails with error: "TypeError: mytest.greet
is not a function in at line number 1"?
Here the idea was to have the user defined class 'MySubClass' which is
loaded in engine scope extend from a class 'MyBaseClass' defined inside the
GWT module and in global scope.
If I change ---------->(1) marked above, to use 'context' instead of
'gBindings', it all works fine. But as I said our intention is to make use
of global and engine scopes to make it perform better.
Can someone tell what really is the issue here? Is this not a supported
pattern?
Thanks in advance
More information about the nashorn-dev
mailing list