You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@ant.apache.org by bo...@apache.org on 2020/09/25 19:13:26 UTC
[ant] 03/03: enable Nashorn compatibility when running GraalVM JS
This is an automated email from the ASF dual-hosted git repository.
bodewig pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ant.git
commit a83708498058dfe59a50d40a982050837b1d397d
Author: Stefan Bodewig <bo...@apache.org>
AuthorDate: Fri Sep 25 21:12:37 2020 +0200
enable Nashorn compatibility when running GraalVM JS
and add a magic property to disable it again
---
WHATSNEW | 8 +++-
build.xml | 46 ++++++++++++++++++-
manual/Tasks/script.html | 7 +++
manual/running.html | 9 ++++
.../testcases/taskdefs/optional/script/graal.xml | 28 ++++++++++++
src/main/org/apache/tools/ant/MagicNames.java | 12 +++++
.../tools/ant/util/optional/JavaxScriptRunner.java | 15 +++++-
.../script/graal/AbstractNashornCompatTest.java | 53 ++++++++++++++++++++++
.../script/graal/DefaultNashornCompatTest.java | 25 ++++++++++
.../script/graal/DisableNashornCompatTest.java | 41 +++++++++++++++++
.../script/graal/EnableNashornCompatTest.java | 25 ++++++++++
11 files changed, 266 insertions(+), 3 deletions(-)
diff --git a/WHATSNEW b/WHATSNEW
index 2632974..2ff4e0e 100644
--- a/WHATSNEW
+++ b/WHATSNEW
@@ -39,7 +39,13 @@ Other changes:
* added some special code to support GraalVM JavaScript as
javax.script scripting engine for JavaScript. In particular we
relax some security settings of GraalVM so that scripts can access
- Ant objects. See the script task manual for additional details.
+ Ant objects.
+
+ Also Ant enables Nashorn compatibility mode by default, you can
+ disable that by setting the magic Ant property
+ ant.disable.graal.nashorn.compat to true.
+
+ See the script task manual for additional details.
* If the magic property ant.tmpdir hasn't been set and Ant can
control the permissions of directories it creates it will create an
diff --git a/build.xml b/build.xml
index 4e157d6..3e75320 100644
--- a/build.xml
+++ b/build.xml
@@ -336,6 +336,10 @@
</or>
</selector>
+ <selector id="needs.graaljs">
+ <filename name="${optional.package}/script/graal/*"/>
+ </selector>
+
<selector id="ant.launcher">
<filename name="${ant.package}/launch/"/>
</selector>
@@ -503,6 +507,9 @@
<available property="javamail.present"
classname="javax.mail.Transport"
classpathref="classpath" ignoresystemclasses="${ignoresystemclasses}"/>
+ <available property="graaljs.present"
+ classname="com.oracle.truffle.js.scriptengine.GraalJSScriptEngine"
+ classpathref="classpath" ignoresystemclasses="${ignoresystemclasses}"/>
<condition property="tests.and.ant.share.classloader">
<or>
@@ -1870,7 +1877,41 @@ ${antunit.reports}
</junitreport>
</target>
- <target name="junit-tests" depends="junit-batch,junit-single-test"/>
+ <target name="junit-tests" depends="junit-batch,graaljs-tests,junit-single-test"/>
+
+ <target name="graaljs-tests" depends="compile-tests,test-init"
+ if="graaljs.present">
+ <junit printsummary="${junit.summary}"
+ haltonfailure="${test.haltonfailure}"
+ fork="true"
+ forkmode="perTest"
+ tempdir="${build.dir}"
+ failureproperty="junit.failed"
+ errorproperty="junit.failed"
+ filtertrace="${junit.filtertrace}">
+ <sysproperty key="ant.home" value="${ant.home}"/>
+ <sysproperty key="build.classes.value" value="${build.classes.value}"/>
+ <sysproperty key="build.tests.value" value="${build.tests.value}"/>
+ <sysproperty key="offline" value="${offline}"/>
+ <sysproperty key="tests-classpath.value"
+ value="${toString:tests-runtime-classpath}"/>
+ <sysproperty key="root" file="${basedir}"/>
+ <sysproperty key="build.compiler" value="${build.compiler}"/>
+ <sysproperty key="tests.and.ant.share.classloader"
+ value="${tests.and.ant.share.classloader}"/>
+ <sysproperty key="java.io.tmpdir" file="${build.junit.tmpdir}"/>
+ <classpath>
+ <path refid="tests-runtime-classpath"/>
+ <pathelement location="${junit.collector.dir}"/>
+ </classpath>
+ <formatter type="xml"/>
+ <batchtest todir="${build.junit.xml}" unless="hasFailingTests">
+ <fileset dir="${src.junit}" excludes="**/Abstract*">
+ <selector refid="needs.graaljs" if="graaljs.present"/>
+ </fileset>
+ </batchtest>
+ </junit>
+ </target>
<target name="junit-batch" depends="compile-tests,test-init" if="junit.batch">
@@ -1907,6 +1948,9 @@ ${antunit.reports}
<exclude name="${taskdefs.package}/TestProcess.java"/>
<exclude name="${optional.package}/splash/SplashScreenTest.java"/>
+ <!-- GraalVM JavaScript Nashorn compat tests influencing current JVM -->
+ <exclude name="${optional.package}/script/graal/"/>
+
<!-- only run these tests if their required libraries are installed -->
<selector refid="conditional-patterns"/>
diff --git a/manual/Tasks/script.html b/manual/Tasks/script.html
index e029cd9..32c2a91 100644
--- a/manual/Tasks/script.html
+++ b/manual/Tasks/script.html
@@ -293,6 +293,13 @@ compatibility script</a>: <code>load("nashorn:mozilla_compat.js");</code>.</p>
Graal's <a href="https://github.com/graalvm/graaljs/blob/master/docs/user/NashornMigrationGuide.md">Nashorn
Migration Guide</a> for more details.</p>
+<p>When using GraalVM JavaScript Ant will enable the
+ feature <code>polyglot.js.allowAllAccess</code> in order to allow
+ scripts to use Ant objects. By default it will also enable Nashorn
+ compatibility mode, but you can disable this by setting the magic
+ Ant property <code>ant.disable.graal.nashorn.compat</code>
+ to <code>true</code>.</p>
+
<p>The <code><script></code> task populates the Project instance under the
name <code class="code">project</code>, so we can use that reference. Another way is to use its
given name or getting its reference from the task itself. The Project provides methods for accessing
diff --git a/manual/running.html b/manual/running.html
index 63647f8..bca2ea2 100644
--- a/manual/running.html
+++ b/manual/running.html
@@ -479,6 +479,15 @@ And I filtered out the <code>getPropertyHelper</code> access.</p>
from within the build file.<br/>
See also <a href="#tmpdir">Temporary Directories</a>.</td>
</tr>
+<tr>
+ <td><code>ant.disable.graal.nashorn.compat</code></td>
+ <td>boolean (default <q>false</q>)</td>
+ <td><em>Since Ant 1.10.9</em><br/>
+ By default Ant will enable GraalVM JavaScript's Nashorn
+ compatibility mode for <code>script</code> and friends. You can
+ disable this beahvior by setting this property to <q>true</q>.<br/>
+ See also the <a href="Tasks/script.html">script task manual</a>.</td>
+</tr>
</table>
<p>
diff --git a/src/etc/testcases/taskdefs/optional/script/graal.xml b/src/etc/testcases/taskdefs/optional/script/graal.xml
new file mode 100644
index 0000000..42a69c5
--- /dev/null
+++ b/src/etc/testcases/taskdefs/optional/script/graal.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ https://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project name="squares">
+ <target name="run-squares-test">
+ <script language="javascript" manager="javax"> <![CDATA[
+ for (i = 1; i <= 10; i++) {
+ echo = squares.createTask("echo");
+ echo.setMessage(i*i);
+ echo.perform();
+ }
+ ]]> </script>
+ </target>
+</project>
diff --git a/src/main/org/apache/tools/ant/MagicNames.java b/src/main/org/apache/tools/ant/MagicNames.java
index 8ced505..12fbcf7 100644
--- a/src/main/org/apache/tools/ant/MagicNames.java
+++ b/src/main/org/apache/tools/ant/MagicNames.java
@@ -347,5 +347,17 @@ public final class MagicNames {
* @since Ant 1.10.9
*/
public static final String AUTO_TMPDIR = "ant.auto.tmpdir";
+
+ /**
+ * Magic property that can be used to disable Nashorn compatibility mode when using GraalVM JavaScript as script
+ * engine.
+ *
+ * <p>Set this to "true" if you want to disable Nashorn compatibility mode.</p>
+ *
+ * Value: {@value}
+ * @since Ant 1.10.9
+ */
+ public static final String DISABLE_NASHORN_COMPAT = "ant.disable.graal.nashorn.compat";
+
}
diff --git a/src/main/org/apache/tools/ant/util/optional/JavaxScriptRunner.java b/src/main/org/apache/tools/ant/util/optional/JavaxScriptRunner.java
index a9b565c..591744e 100644
--- a/src/main/org/apache/tools/ant/util/optional/JavaxScriptRunner.java
+++ b/src/main/org/apache/tools/ant/util/optional/JavaxScriptRunner.java
@@ -193,7 +193,10 @@ public class JavaxScriptRunner extends ScriptRunnerBase {
if (keptEngine != null) {
return keptEngine;
}
- ScriptEngine result =
+ if (languageIsJavaScript()) {
+ maybeEnableNashornCompatibility();
+ }
+ final ScriptEngine result =
new ScriptEngineManager().getEngineByName(getLanguage());
if (result == null && JavaEnvUtils.isAtLeastJavaVersion("15")
&& languageIsJavaScript()) {
@@ -219,6 +222,16 @@ public class JavaxScriptRunner extends ScriptRunnerBase {
}
}
+ private static final String ENABLE_NASHORN_COMPAT_IN_GRAAL = "polyglot.js.nashorn-compat";
+
+ private void maybeEnableNashornCompatibility() {
+ if (getProject() != null) {
+ System.setProperty(ENABLE_NASHORN_COMPAT_IN_GRAAL,
+ Project.toBoolean(getProject().getProperty(MagicNames.DISABLE_NASHORN_COMPAT))
+ ? "false" : "true");
+ }
+ }
+
private final static List<String> JS_LANGUAGES = Arrays.asList("js", "javascript");
private boolean languageIsJavaScript() {
diff --git a/src/tests/junit/org/apache/tools/ant/taskdefs/optional/script/graal/AbstractNashornCompatTest.java b/src/tests/junit/org/apache/tools/ant/taskdefs/optional/script/graal/AbstractNashornCompatTest.java
new file mode 100644
index 0000000..25123d2
--- /dev/null
+++ b/src/tests/junit/org/apache/tools/ant/taskdefs/optional/script/graal/AbstractNashornCompatTest.java
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.script.graal;
+
+import org.apache.tools.ant.BuildFileRule;
+import org.apache.tools.ant.MagicNames;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.hamcrest.Matchers.containsString;
+import static org.junit.Assert.assertThat;
+
+public class AbstractNashornCompatTest {
+
+ private final String magicPropertyValue;
+
+ public AbstractNashornCompatTest(String magicPropertyValue) {
+ this.magicPropertyValue = magicPropertyValue;
+ }
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/taskdefs/optional/script/graal.xml");
+ buildRule.getProject().setProperty(MagicNames.DISABLE_NASHORN_COMPAT, magicPropertyValue);
+ }
+
+ @Test
+ public void runSquaresTest() {
+ buildRule.executeTarget("run-squares-test");
+ assertThat("Expecting the square of 7 to be logged", buildRule.getLog(),
+ containsString("49"));
+ }
+}
diff --git a/src/tests/junit/org/apache/tools/ant/taskdefs/optional/script/graal/DefaultNashornCompatTest.java b/src/tests/junit/org/apache/tools/ant/taskdefs/optional/script/graal/DefaultNashornCompatTest.java
new file mode 100644
index 0000000..a5c1771
--- /dev/null
+++ b/src/tests/junit/org/apache/tools/ant/taskdefs/optional/script/graal/DefaultNashornCompatTest.java
@@ -0,0 +1,25 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.script.graal;
+
+public class DefaultNashornCompatTest extends AbstractNashornCompatTest {
+
+ public DefaultNashornCompatTest() {
+ super(null);
+ }
+}
diff --git a/src/tests/junit/org/apache/tools/ant/taskdefs/optional/script/graal/DisableNashornCompatTest.java b/src/tests/junit/org/apache/tools/ant/taskdefs/optional/script/graal/DisableNashornCompatTest.java
new file mode 100644
index 0000000..808bdee
--- /dev/null
+++ b/src/tests/junit/org/apache/tools/ant/taskdefs/optional/script/graal/DisableNashornCompatTest.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.script.graal;
+
+import org.apache.tools.ant.BuildException;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+
+public class DisableNashornCompatTest extends AbstractNashornCompatTest {
+
+ @Rule
+ public ExpectedException thrown = ExpectedException.none();
+
+ public DisableNashornCompatTest() {
+ super("true");
+ }
+
+ @Test
+ @Override
+ public void runSquaresTest() {
+ thrown.expect(BuildException.class);
+ thrown.expectMessage("TypeError");
+ super.runSquaresTest();
+ }
+}
diff --git a/src/tests/junit/org/apache/tools/ant/taskdefs/optional/script/graal/EnableNashornCompatTest.java b/src/tests/junit/org/apache/tools/ant/taskdefs/optional/script/graal/EnableNashornCompatTest.java
new file mode 100644
index 0000000..2161b6f
--- /dev/null
+++ b/src/tests/junit/org/apache/tools/ant/taskdefs/optional/script/graal/EnableNashornCompatTest.java
@@ -0,0 +1,25 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.script.graal;
+
+public class EnableNashornCompatTest extends AbstractNashornCompatTest {
+
+ public EnableNashornCompatTest() {
+ super("false");
+ }
+}