Ad NashornScriptEngine (Re: FXMLLoader: not supplying filename to script engine, not supplying event object as argument to script

Rony G. Flatscher Rony.Flatscher 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":

[2] Sundararajan A., "Nashorn, javax.script.filename, and load()":

[3] "JDK-8050432 : javax.script.filename variable should not be enumerable with nashorn engine's
ENGINE_SCOPE bindings": <>

[4] Oracle, "Java Platform, Standard Edition Nashorn User's Guide":


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
( entry and

   b) does not honor the ScriptEngine.ARGV (cf.
<>) 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?


More information about the openjfx-dev mailing list