8

I have a Maven project using an Ant build file:

<?xml version='1.0' encoding='UTF-8'?>
<project>
   <modelVersion>4.0.0</modelVersion>
   <artifactId>my-test-app</artifactId>
   <groupId>my-test-group</groupId>
   <version>1.0-SNAPSHOT</version>

   <build>
      <plugins>
         <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-antrun-plugin</artifactId>
            <version>1.8</version>
            <executions>
               <execution>
                  <id>compile</id>
                  <phase>compile</phase>
                  <configuration>
                     <target>
                        <ant antfile="build.xml" inheritRefs="true">
                           <target name="all"/>
                        </ant>
                     </target>
                  </configuration>
                  <goals>
                     <goal>run</goal>
                  </goals>
               </execution>
            </executions>
         </plugin>
      </plugins>
   </build>
</project>

The Ant build file uses a script:

<?xml version='1.0' encoding='UTF-8'?>
<project name="scriptdef-test-build">
   <scriptdef name="test-script" language="javascript">
      <![CDATA[
           var System = Java.type('java.lang.System');
           System.out.println("Working!");
        ]]>
   </scriptdef>
   <target name="all">
      <test-script/>
   </target>
</project>

On Java 8 it works, but on Java 9 (9-ea+162) it can't find the script engine:

org.apache.maven.lifecycle.LifecycleExecutionException: Failed to execute goal org.apache.maven.plugins:maven-antrun-plugin:1.8:run (compile) on project my-test-app: An Ant BuildException has occured: The following error occurred while executing this line:
/home/dan/scriptdef-test/build.xml:10: Unable to create javax script engine for javascript
around Ant part ...<ant antfile="build.xml" inheritRefs="true">... @ 4:47 in /home/dan/scriptdef-test/target/antrun/build-main.xml
...    
Caused by: /home/dan/scriptdef-test/build.xml:10: Unable to create javax script engine for javascript
    at org.apache.tools.ant.util.optional.JavaxScriptRunner.evaluateScript(JavaxScriptRunner.java:84)
    at org.apache.tools.ant.util.optional.JavaxScriptRunner.executeScript(JavaxScriptRunner.java:67)
    at org.apache.tools.ant.taskdefs.optional.script.ScriptDef.executeScript(ScriptDef.java:350)
    at org.apache.tools.ant.taskdefs.optional.script.ScriptDefBase.execute(ScriptDefBase.java:50)
    at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:292)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:547)
    at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:106)
    at org.apache.tools.ant.Task.perform(Task.java:348)
    at org.apache.tools.ant.Target.execute(Target.java:435)
    at org.apache.tools.ant.Target.performTasks(Target.java:456)
    at org.apache.tools.ant.Project.executeSortedTargets(Project.java:1393)
    at org.apache.tools.ant.helper.SingleCheckExecutor.executeTargets(SingleCheckExecutor.java:38)
    at org.apache.tools.ant.Project.executeTargets(Project.java:1248)
    at org.apache.tools.ant.taskdefs.Ant.execute(Ant.java:441)
    ... 34 more

I have attached a debugger and I saw that the ScriptEngineManager used by JavaxScriptRunner doesn't have any script engines, because the service loader it uses doesn't find any ScriptEngineFactory implementations. How can I get the service loader to work?

Update: I've also created an issue for this: https://issues.apache.org/jira/browse/MANTRUN-200

Dan Berindei
  • 7,054
  • 3
  • 41
  • 48
  • Why do you need to havae an Ant build script which than uses a JavaScript part sounds a little bit weird to me... – khmarbaise Mar 28 '17 at 12:32
  • It is a bit weird, I agree, but I don't know even half of what's going on in these build files, so I'm not really keen to change them. – Dan Berindei Mar 28 '17 at 13:02
  • The only module I found that provides a `ScriptEngineFactory` is _jdk.scripting.nashorn_. Try adding `--add-modules jdk.scripting.nashorn` to the `java` command that ends up complaining about the missing engine. – Nicolai Parlog Mar 28 '17 at 18:34
  • @Nicolai I tried that, and also `--add-opens jdk.scripting.nashorn/jdk.nashorn.api.scripting=ALL-UNNAMED`, but it didn't make a difference. – Dan Berindei Mar 29 '17 at 12:11
  • 1
    Add classpathref="maven.plugin.classpath" attribute to scriptdef tag. – Cristian Florescu Oct 17 '17 at 07:18
  • @myset it didn't work. – Dan Berindei Oct 19 '17 at 10:57
  • @Nicolai Can you elaborate more on your suggestion ? where can I add the argument ? – Arar May 20 '18 at 20:51
  • @SaifMasadeh Have a look at [this post](https://blog.codefx.org/tools/maven-on-java-9/#Configuring-The-Build-For-Java-8-And-Java-9) for Mavne on Java 9 – Nicolai Parlog May 21 '18 at 14:25
  • Although MANTRUN-200 is marked closed, the issue remains (see linked issue [MNG-6275](https://issues.apache.org/jira/browse/MNG-6275)). I had a different, but related use-case - so could directly use `jdk.nashorn.api.scripting.NashornScriptEngineFactory` - but it appears hacking SPI with something on plugin's classpath containing `META-INF/services/javax.script.ScriptEngineFactory` cannot work (due to wider issue on MNG-6275). – earcam Nov 26 '18 at 00:59

2 Answers2

3

My fix was to change our scripts to Groovy, but I got a notification about this question and went back to see if the issue is fixed. It's not fixed, but a comment led me to a working solution:

<?xml version='1.0' encoding='UTF-8'?>
<project name="scriptdef-test-build">
   <scriptdef name="test-javascript" language="javascript"
              classpath="${plugin_classpath}">
      <![CDATA[
           var System = Java.type('java.lang.System');
           System.out.println("Working from Javascript!");
        ]]>
   </scriptdef>

   <target name="all">
      <property name="plugin_classpath" refid="maven.plugin.classpath"/>
      <test-groovy/>
      <test-javascript/>
   </target>
</project>
Dan Berindei
  • 7,054
  • 3
  • 41
  • 48
  • the `plugin_classpath` property is the important part: Define it and use it in the `scriptdef` – bebbo Dec 28 '21 at 15:56
0

Dan Berindei's solution works with JDK 11 and config embedded in the plugin as well:

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-antrun-plugin</artifactId>
  <executions>
    <execution>
      <!-- id/phase/goals here -->
      <configuration>
        <target>
          <property name="plugin_classpath" refid="maven.plugin.classpath"/>

          <script language="javascript" classpath="${plugin_classpath}"><![CDATA[
            project.setProperty('resultCode', 
                parseInt(project.getProperty('copyResult')));
          ]]></script>
        </target>
      </configuration>
    </execution>
  </executions>
</plugin>

Works with Ant's scriptcondition too:

<scriptcondition language="javascript" classpath="${plugin_classpath}"><![CDATA[
   <!-- your script here... -->
]]></scriptcondition>
user944849
  • 14,524
  • 2
  • 61
  • 83