Bug 64469 - Ant build.xml fails with "Unable to create javax script engine for javascript" with latest JDK 15 due to removal of Nashorn
Summary: Ant build.xml fails with "Unable to create javax script engine for javascript...
Status: NEW
Alias: None
Product: Ant
Classification: Unclassified
Component: Core tasks (show other bugs)
Version: 1.10.8
Hardware: PC Linux
: P2 normal (vote)
Target Milestone: ---
Assignee: Ant Notifications List
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2020-05-24 05:53 UTC by Dominik Stadler
Modified: 2020-05-28 06:41 UTC (History)
0 users



Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Dominik Stadler 2020-05-24 05:53:53 UTC
The Javascript engine was deprecated in JDK 11 and now removed JKD 15, see https://openjdk.java.net/jeps/372 for details. 

Ant uses it for providing the <scriptdef> and <script> task.

Apache POI uses Apache Ant for building. When testing the build with the latest JDK 15 pre-release 15-ea+24-1168, the build fails because it uses the <scriptdef> task, but the Javascript implementation "Nashorn" was removed from the JDK now.

Output is:

    build.xml:122: Unable to create javax script engine for javascript

I tried to use the supported engine "bsf", but I could not find documentation about how to actually make it work and some simple tries resulted in "Unable to load the BSF script engine manager (org.apache.bsf.BSFManager)" when using 3.x, with 2.4.0 it worked a bit more, but also failed, because simple things like String.replace(Regex, String) are not supported.

See https://golb.hplar.ch/2020/04/java-javascript-engine.html for a possible replacement via graal-js. However when trying to use this implementation in Ant, I get an error "Unsupported language prefix graal.js", so Ant seems to currently hardcode the list of implementations, see https://github.com/apache/ant/blob/master/src/main/org/apache/tools/ant/util/ScriptRunnerCreator.java

So it seems for full support of JDK 15, Ant will need to allow to switch to another Javascript implementation, e.g. graal-js as the only current option "bsf" is not a good replacement upon a quick look.
Comment 1 Stefan Bodewig 2020-05-26 16:10:29 UTC
When I disabled the script tests for JDK 15+ I very quickly looked into using grall,js instead - but it seemed to involve quite a bit more than I was willing to chew on back then. Any helo is much appreciated.

BSF seems to be more or less dead - it has become part of the Apache Commons Project but the last commit that changed anything but infrastructure stuff has happened more than five years ago.

I believe, even when using graal.js the Ant ScriptRunner's "manager" should still be "javax" as this is the API we are using. AFAIU graal.js is the "language" you need to set. At least this is from a cursory glance at the migration guide you link to. We call "createEngine" here https://github.com/apache/ant/blob/master/src/main/org/apache/tools/ant/util/optional/JavaxScriptRunner.java#L193
Comment 2 Dominik Stadler 2020-05-26 20:56:37 UTC
Thanks for the hints, when trying GraalJS this way I am stuck at the following:

Finding class org.graalvm.polyglot.Engine
[propertyreset] ScriptEngineManager providers.next(): javax.script.ScriptEngineFactory: Provider com.oracle.truffle.js.scriptengine.GraalJSEngineFactory could not be instantiated

I supplied the following jars: 

js-20.1.0.jar  
js-launcher-20.1.0.jar  
js-scriptengine-20.1.0.jar

maybe I am missing some more? ant -debug did not provide more information.
Comment 3 Stefan Bodewig 2020-05-27 05:55:07 UTC
I am getting closer by using the Maven Ant tasks in Ant's own fetch.xml. I told it to download the equivalent of

    <dependency>
      <groupId>org.graalvm.js</groupId>
      <artifactId>js</artifactId>
      <version>20.1.0</version>
    </dependency>  
    <dependency>
      <groupId>org.graalvm.js</groupId>
      <artifactId>js-scriptengine</artifactId>
      <version>20.1.0</version>
    </dependency>

which resulted in

Downloading: org/graalvm/js/js/20.1.0/js-20.1.0.pom from repository central at https://repo1.maven.org/maven2/
Transferring 3K from central
Downloading: org/graalvm/regex/regex/20.1.0/regex-20.1.0.pom from repository central at https://repo1.maven.org/maven2/
Transferring 1K from central
Downloading: org/graalvm/truffle/truffle-api/20.1.0/truffle-api-20.1.0.pom from repository central at https://repo1.maven.org/maven2/
Transferring 1K from central
Downloading: org/graalvm/sdk/graal-sdk/20.1.0/graal-sdk-20.1.0.pom from repository central at https://repo1.maven.org/maven2/
Transferring 1K from central
Downloading: com/ibm/icu/icu4j/66.1/icu4j-66.1.pom from repository central at https://repo1.maven.org/maven2/
Transferring 5K from central
Downloading: org/graalvm/regex/regex/20.1.0/regex-20.1.0.jar from repository central at https://repo1.maven.org/maven2/
Downloading: org/graalvm/sdk/graal-sdk/20.1.0/graal-sdk-20.1.0.jar from repository central at https://repo1.maven.org/maven2/
Downloading: org/graalvm/js/js/20.1.0/js-20.1.0.jar from repository central at https://repo1.maven.org/maven2/
Downloading: org/graalvm/truffle/truffle-api/20.1.0/truffle-api-20.1.0.jar from repository central at https://repo1.maven.org/maven2/
Downloading: com/ibm/icu/icu4j/66.1/icu4j-66.1.jar from repository central at https://repo1.maven.org/maven2/
Transferring 2502K from central
Transferring 12632K from central
Transferring 5331K from central
Transferring 524K from central
Transferring 16132K from central
Copying 10 files to /home/stefan/devel/ASF/ant/lib/optional
Downloading: org/graalvm/js/js-scriptengine/20.1.0/js-scriptengine-20.1.0.pom from repository central at https://repo1.maven.org/maven2/
Transferring 1K from central
Downloading: org/graalvm/js/js-scriptengine/20.1.0/js-scriptengine-20.1.0.jar from repository central at https://repo1.maven.org/maven2/
Transferring 57K from central
Copying 1 file to /home/stefan/devel/ASF/ant/lib/optional

with this I can create the engine but it looks as if exposing beans  to graal.js needs something more than we've done for Nashorn. Bassed on Ant's manual I created

<project name="squares" default="main" basedir=".">
  <target name="main">
    <script language="graal.js" manager="javax"> <![CDATA[
      for (i = 1; i <= 10; i++) {
        echo = squares.createTask("echo");
        echo.setMessage(i*i);
        echo.perform();
      }
    ]]> </script>
  </target>
</project>

and with this I get

BUILD FAILED
/tmp/js.xml:3: TypeError: invokeMember (createTask) on org.apache.tools.ant.Project@3fc79729 failed due to: Unknown identifier: createTask
	at <js> :program(<eval>:3:51-76)
	at org.graalvm.polyglot.Context.eval(Context.java:345)

so the engine has been loaded and has access to the Project instance but cannot invoke the createTask method. I'll try to spend some more time with it at the weekend, but maybe you can get a step further with the full list of dependencies.
Comment 4 Stefan Bodewig 2020-05-27 06:08:32 UTC
I got this to work when setting the system property polyglot.js.nashorn-compat to true. See https://www.graalvm.org/docs/reference-manual/languages/js/

This is not satisfying, I need to look into what needs to be done in order to avoid that.

Aside: at least on Java 8 Ant's own scriptdef test that I disabled for Java 15 with https://github.com/apache/ant/commit/dffd57ca23bcb6e8f40d14a9d1f49d143b2dc8d3 fails as the compiled script on graal.js is slower than the uncompiled version (and significantly so).
Comment 5 Stefan Bodewig 2020-05-27 07:12:25 UTC
you may want to give the graal.js branch a try. https://github.com/graalvm/graaljs/blob/master/docs/user/ScriptEngine.md guided me to unrestrict graal.js so the script is allowed to do as much as the old Nashorn engine would allow.

I had to adapt the js example which contained

    echo.setMessage(i*i);

Here Nashorn must have magically translated the Javascript number to a String, graal.js is not willing to go that far (but seems to do so in Nashorn compatibility mode).
Comment 6 Stefan Bodewig 2020-05-27 16:10:43 UTC
I've merged my changes to master and will discuss a few things I found out by now on the dev list
Comment 7 Dominik Stadler 2020-05-28 06:06:23 UTC
Thanks a lot for your work!

It seems to mostly work now with the version from master, some additional jar-files were necessary to support regex and others, unfortunately the error message in Graal.js is not very specific about the reason.
Comment 8 Stefan Bodewig 2020-05-28 06:41:05 UTC
I guess we will have a bit of documentation to do.

One thing I haven't made up my mind about is whether we should enable full Nashorn compatibility or not by default, but I tend to not do so and leave it to people who run the build - but tell them to set a system property before starting Ant if they need to.