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 <bode...@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"); + } +}