Ad NashornScriptEngine (Re: FXMLLoader: not supplying filename to script engine, not supplying event object as argument to script
Rony G. Flatscher
Rony.Flatscher at wu.ac.at
Thu Nov 14 15:34:04 UTC 2019
On 13.11.2019 19:50, Kevin Rushforth wrote:
>
> On 11/13/2019 9:42 AM, Rony G. Flatscher wrote:
>> Will come up with a short reproducible testcase in ooRexx with brief comments such that the testcase
>> could be understood without the runtime (ooRexx reads almost like pseudo-code).
>>
>> To reproduce the testcase one would need ooRexx and the Java bridge BSF4ooRexx (all opensource) for
>> which I could come up with a zip-archive (assuming binaries within should be 64-bit) and a script to
>> set up the environment either for Windows, Linux or MacOS, whatever you advise. Would that be o.k.?
>
> We prefer not to rely on third-party libraries for test cases. In any case we would not be able to
> use that for a regression test / unit test.
Yes, this is understandable.
> How hard to you think it would be to use NashornScriptEngine for a test case?
Probably impossible. Have researched NashornScriptEngine a little bit for a couple of hours now in
order to assess it with respect to writing a testcase to demonstrate the problem.
According to [1] the implementation has some Nashorn specific uses with respect to the ENGINE_SCOPE
Bindings like:
- "... The default context's ENGINE_SCOPE is a wrapped instance of ECMAScript "global" object -
which is the "this" in top level script expressions. ..."
- "... Please note that the context's GLOBAL_SCOPE Bindings and nashorn global object are
different. Nashorn's global object is associated with ENGINE_SCOPE and not with GLOBAL_SCOPE.
GLOBAL_SCOPE object of default script context is a javax.script.SimpleBindings instance. ..."
- "... If you create a new ScriptContext object and use it to evaluate scripts, then ENGINE_SCOPE of
that context has to be associated with a nashorn Global object somehow - or else script execution is
not possible with that context - this is because evaluated script expects standard ECMAScript global
builtins always. ..."
- "... But, user can supply any ScriptContext implementation containing any Bindings object as
ENGINE_SCOPE, nashorn engine cannot always assume ENGINE_SCOPE Bindings to be backed by a nashorn
Global instance. Nashorn engine checks if ENGINE_SCOPE of the ScriptContext is backed by a Nashorn
Global object or not. If not, it creates a fresh Bindings backed by a nashorn Global instance and
associates the same with the ENGINE_SCOPE that the user provided. ..."
- "... Limitations/Known issues / While nashorn attempts to give a seamless illusion of
ScriptObjectMirrors and JSObjects, not every operation and script API (JSON, Array, Function's
properties/functions) treats ScriptObjectMirror and jdk.nashorn.internal.runtime.ScriptObject
uniformly. There are places where ScriptObjects work as expected but if you pass ScriptObjectMirror
or your own JSObject implementation, it won't work as expected. ..."
[2] states: "Summary: Nashorn uses javax.script.filename uses as "source name" of the generated
class *only* for engine.eval calls. For "load", it uses the URL/file name of the loaded script as
"source name". As for javax.script.filename variable, Nashorn never sets - only uses it."
In addition [3] indicates that scripts themselves should not get access to ScriptEngine.FILENAME.
Indeed, adding the entry ScriptEngine.FILENAME to the NashornScriptEngine supplied ENGINE_SCOPE
Bindings (which will be of type "jdk.nashorn.api.scripting.ScriptObjectMirror") will not leave that
entry in the Bindings.
Also, invoking a Javascript script stored in a file via ScriptEngine.eval() does not make the
arguments (entry ScriptEngine.ARGV) available to the invoked Javascript script (i.e.
"arguments.length" will return 0), e.g. in the following testscript.js:
print( "hi, this is from 'testargs.js', arguments.length="+arguments.length);
print( "arguments.length: " + arguments.length );
print( "---")
func1 ( "uno", "deux", 3);
function func1(a, b, c) {
print( "--> func1(a, b, c) - arguments.length: " + arguments.length );
print( "\ta: "+ a + " / arguments[0]: " + arguments[0] );
print( "\tb: "+ b + " / arguments[1]: " + arguments[1] );
print( "\tc: "+ c + " / arguments[2]: " + arguments[2] );
}
Doing a ScriptEngine.eval() with the ENGINE_SCOPE Bindings possessing the argument entry by the name
of ScriptEngine.ARGV will yield the following output in this case:
hi, this is from 'testargs.js', arguments.length=0
arguments.length: 0
---
--> func1(a, b, c) - arguments.length: 3
a: uno / arguments[0]: uno
b: deux / arguments[1]: deux
c: 3 / arguments[2]: 3
[1] Sundararajan A., "Nashorn jsr223 engine notes":
<https://wiki.openjdk.java.net/display/Nashorn/Nashorn+jsr223+engine+notes>
[2] Sundararajan A., "Nashorn, javax.script.filename, and load()":
<http://mail.openjdk.java.net/pipermail/nashorn-dev/2015-July/004932.html>
[3] "JDK-8050432 : javax.script.filename variable should not be enumerable with nashorn engine's
ENGINE_SCOPE bindings": <https://bugs.java.com/bugdatabase/view_bug.do?bug_id=8050432>
[4] Oracle, "Java Platform, Standard Edition Nashorn User's Guide":
<https://docs.oracle.com/javase/8/docs/technotes/guides/scripting/nashorn/toc.html>
---
So concluding that the NashornScriptEngine will not be an implementation that could be used to
create a testcase to demonstrate the problem and to create a testunit, because of its specific
implementation that
a) swallows the ScriptEngine.FILENAME
(https://docs.oracle.com/javase/8/docs/api/javax/script/ScriptEngine.html#FILENAME) entry and
b) does not honor the ScriptEngine.ARGV (cf.
<https://docs.oracle.com/javase/8/docs/api/javax/script/ScriptEngine.html#ARGV>) entry.
Would you have other suggestions for scripting engines that you think could be used instead, such
that I can take a look at its implementation and try to create a testcase with it?
---rony
More information about the openjfx-dev
mailing list