"Internal review ID : 9062887" (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 21 14:29:52 UTC 2019


On 15.11.2019 16:08, Rony G. Flatscher wrote:
> On 14.11.2019 22:57, Kevin Rushforth wrote:
>> On 11/14/2019 10:12 AM, Rony G. Flatscher wrote:
>>> On 14.11.2019 16:34, Rony G. Flatscher wrote:
>>>> On 13.11.2019 19:50, Kevin Rushforth wrote:
>>>>> On 11/13/2019 9:42 AM, Rony G. Flatscher wrote:
>>> ... cut ...
>>>>>> 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.
>>> If test units really seem to be important in this particular case, one possibility would be to
>>> create a minimalistic ScriptEngine implementation in pure Java just for the sole purpose to allow
>>> the creation of a test unit that is able to assert that FXMLLoader puts the ScriptEngine.ARGV and
>>> ScriptEngine.FILENAME entries into the ENGINE_SCOPE Bindings. E.g. having the ScriptEngine's eval()
>>> methods return the ScriptContext at invocation time in order to allow inspection of the Bindings.
>>> This way it would become also possible to write in addition test units that also check whether all
>>> FXML elements that carry a fx:id are really placed into the GLOBAL_SCOPE Bindings.
>> Something like that seems reasonable, and would avoid a dependence on Nashorn, which in addition
>> to having all the problems you mentioned, is deprecated for removal.
>>
>>> However,
>> Did you have something more to add?
> No, sorry for that. Rewrote my e-mail and had sent it too early by mistake and without noticing.
>
> Will study all the procedures and create a testcase to be submitted at <https://bugreport.java.com/>
> as per your advice (and will report back under this thread once submitted). The testcase would use
> an artificial ScriptEngine implementation that could be used for testunit testing as well. This
> might take a while due to other obligations that I will have to meet during the next few days.
>
> ---rony

O.K., so came up with a test case that contains an artificial script engine implementation for
logging the eval() invocations together with the scripts to execute and the ScriptContext
ENGINE_SCOPE and GLOBAL_SCOPE Bindings at the time of the invocation. (It is meant to be also usable
for creating script engine related test units for Java script hosts.)

Packaged the source and binaries of that script engine as jar file that one merely needs to put on
the CLASSPATH or add as a module.

An updated FXMLLoader patch suggesting a fix is included as well. This version appends the line
number to the file name if the script to be evaluated is embedded in the fxml-file, such that in
case of an error it becomes possible to quickly find it in larger fxml files.

With the zip-archive done I went to the Oracle Java Bug Database and just entered a bug report at
<https://bugreport.java.com/bugreport/submit_start.do> got the internal "ID : 9062887".

As it was not possible to attach/upload the zip-archive at this point, I will attach the zip-archive
(contains all sources and binaries) to this e-mail. The contained <readme.txt> reads:

    Testcase that demonstrates that FXMLLoader does not set [1]
    ScriptEngine.FILENAME and [2] ScriptEngine.ARGV entries in
    ScriptContext.ENGINE_SCOPE Bindings.

    To run the test case:

    - unzip testcaseFXMLLoaderScriptEngines.zip,

    - change into "testcaseFXMLLoaderScriptEngines" subdirectory,

    - run the testcase by issuing the following command:

      - Unix:

            java -cp .:RgfPseudoScriptEngine.jar FXMLLoaderTestCase4ScriptEngineScope

      - Windows:

            java -cp .;RgfPseudoScriptEngine.jar FXMLLoaderTestCase4ScriptEngineScope

    FXMLLoaderTestCase4ScriptEngineScope loads "demo_01.fxml" which is a controller
    that uses the pseudo script language rgf.scriptEngine.RgfPseudoScriptEngine,
    which logs the eval() invocations with the script code and the Bindings of the
    ScriptContext.

    Comparing "demo_01.fxml" and the output of the above test case demonstrates that
    FXMLLoader does not popuplate the [3] ENGINE_SCOPE Bindings with the filename of
    the script that gets evaluated, nor does add the ARGV entry to the ENGINE_SCOPE
    Bindings in the case of events (just an entry named "event").

    In case of errors (during development or deployment) it is not possible
    therefore to point to the file (external file or the fxml-file defining
    explicitly script code) in which a runtime error has occurred.

    In the case of an event callback, if ARGV was defined the script code could
    directly fetch and interact with the supplied event object argument.  In the
    case that a script engine does not automatically make Bindings entry available
    as implicit variables (e.g.  for scoping reasons) it becomes cumbersome or even
    impossible in some script engine implementations (if they do not provide access
    to the Bindings) to get at the event argument of the callback invocation.

    The JSR-223 specifications lists all the (reserved) ScriptEngine constants that
    are meant to be used as reserved keys for the ENGINE_SCOPE Bindings, whenever
    appropriate cf.  [0] p.  l50 ff.  (A ScriptEngine is supposed to populate and
    maintain the ENGINE_SCOPE Bindings hence the definition of these constants with
    the class.)

    Running the above program on Windows yields the output captured and supplied in
    [4].

    The supplied patch [5] changes FXMLLoader.java such,

    - that the ScriptEngine.FILENAME entry is always set in the ENGINE_SCOPE
      Bindings. In the case that the scripts are hosted in a fxml-file that file
      path will be used together with an appended string that hints at the location
      in the fxml file from where the script has been taken for evaluation. In the
      case of event handling scripts that appended string hints at the location in
      the fxml-file where the event attribute with the script code got used.

    - and that the ScriptEngine.ARGV entry is always set in the ENGINE_SCOPE
      Bindings for event callbacks using the 'event' object as the single argument.

    Applying the patch and running the above program on Linux yields the output
    captured and supplied in [6].

    ---

    The jar-file [7] needs merely to be put on the CLASSPATH (or MODULE_PATH as a
    proper module-info.class is included, the module name is "rgf.scriptEngine") to
    make the pseudo scripting language available and to run the supplied testcase.
    The RgfPseudoScriptEngine (script engine name and extension is "rpsl")
    implementation should also make it possible to create test units for asserting
    that Java script hosts are populating the ScriptContext Bindings according to
    specifications.

    All Java classes come with their source code (the script engine service file and
    module-info.{java|class} are contained in the jar file).

    Having signed the OCA you may use all of the supplied code freely.

    If there is anything you need or that I could provide, please let me know.

    ---rony

    [0] JSR-223 specification at <https://jcp.org/en/jsr/detail?id=223>, download
        <https://jcp.org/aboutJava/communityprocess/pfd/jsr223/index.html>:
        "java_scripting-1_0-fr-spec.pdf"

    [1]
    <https://docs.oracle.com/en/java/javase/11/docs/api/java.scripting/javax/script/ScriptEngine.html#FILENAME>

    [2]
    <https://docs.oracle.com/en/java/javase/11/docs/api/java.scripting/javax/script/ScriptEngine.html#ARGV>

    [3]
    <https://docs.oracle.com/en/java/javase/11/docs/api/java.scripting/javax/script/ScriptContext.html#ENGINE_SCOPE>

    [4] Output of running the testcase on Windows (Java 8): "info/Demo_output_without_fix.txt"

    [5] FXMLLoader patch: "info/diff_add_FILENAME_ARGV_to_FXMLLoader_preferable_20191121.txt"

    [6] Output of running the testcase after patching FXMLLoader with [5] on Linux (OpenJDK 11.0.5):
        "info/Demo_output_with_fix_and_linenumbers.txt"

    [7] Pseudo script engine implementation to be put on the CLASSPATH or MODULE_PATH (module
        name "rgf.scriptEngine"): <RgfPseudoScriptEngine.jar>

    [8] FXML test case:

        - FXMLLoaderTestCase4ScriptEngineScope.{java|class}
          ... loads "demo_01.rxml" and dumps the engine and global Bindings

        - demo_01.fxml
        ... FXML file using scripts in the pseudo script language [7] as controller,
            either as external or embedded scripts, including scripts for event
            handling Action and MouseClicked events

        - demo_01_bottomscript.rpsl  ... serving as external script file

        - demo_01_middlescript.rpsl  ... serving as external script file

        - demo_01_topscript.rpsl     ... serving as external script file

If there is anything else I can/should do, please advise.
(Being on the road in the next few days it might take me until the beginning of next week to get back.)

---rony








More information about the openjfx-dev mailing list