and add a magic property to disable it againmaster
| @@ -39,7 +39,13 @@ Other changes: | |||||
| * added some special code to support GraalVM JavaScript as | * added some special code to support GraalVM JavaScript as | ||||
| javax.script scripting engine for JavaScript. In particular we | javax.script scripting engine for JavaScript. In particular we | ||||
| relax some security settings of GraalVM so that scripts can access | 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 | * If the magic property ant.tmpdir hasn't been set and Ant can | ||||
| control the permissions of directories it creates it will create an | control the permissions of directories it creates it will create an | ||||
| @@ -336,6 +336,10 @@ | |||||
| </or> | </or> | ||||
| </selector> | </selector> | ||||
| <selector id="needs.graaljs"> | |||||
| <filename name="${optional.package}/script/graal/*"/> | |||||
| </selector> | |||||
| <selector id="ant.launcher"> | <selector id="ant.launcher"> | ||||
| <filename name="${ant.package}/launch/"/> | <filename name="${ant.package}/launch/"/> | ||||
| </selector> | </selector> | ||||
| @@ -503,6 +507,9 @@ | |||||
| <available property="javamail.present" | <available property="javamail.present" | ||||
| classname="javax.mail.Transport" | classname="javax.mail.Transport" | ||||
| classpathref="classpath" ignoresystemclasses="${ignoresystemclasses}"/> | 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"> | <condition property="tests.and.ant.share.classloader"> | ||||
| <or> | <or> | ||||
| @@ -1870,7 +1877,41 @@ ${antunit.reports} | |||||
| </junitreport> | </junitreport> | ||||
| </target> | </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"> | <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="${taskdefs.package}/TestProcess.java"/> | ||||
| <exclude name="${optional.package}/splash/SplashScreenTest.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 --> | <!-- only run these tests if their required libraries are installed --> | ||||
| <selector refid="conditional-patterns"/> | <selector refid="conditional-patterns"/> | ||||
| @@ -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 | Graal's <a href="https://github.com/graalvm/graaljs/blob/master/docs/user/NashornMigrationGuide.md">Nashorn | ||||
| Migration Guide</a> for more details.</p> | 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 | <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 | 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 | given name or getting its reference from the task itself. The Project provides methods for accessing | ||||
| @@ -479,6 +479,15 @@ And I filtered out the <code>getPropertyHelper</code> access.</p> | |||||
| from within the build file.<br/> | from within the build file.<br/> | ||||
| See also <a href="#tmpdir">Temporary Directories</a>.</td> | See also <a href="#tmpdir">Temporary Directories</a>.</td> | ||||
| </tr> | </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> | </table> | ||||
| <p> | <p> | ||||
| @@ -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> | |||||
| @@ -347,5 +347,17 @@ public final class MagicNames { | |||||
| * @since Ant 1.10.9 | * @since Ant 1.10.9 | ||||
| */ | */ | ||||
| public static final String AUTO_TMPDIR = "ant.auto.tmpdir"; | 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"; | |||||
| } | } | ||||
| @@ -193,7 +193,10 @@ public class JavaxScriptRunner extends ScriptRunnerBase { | |||||
| if (keptEngine != null) { | if (keptEngine != null) { | ||||
| return keptEngine; | return keptEngine; | ||||
| } | } | ||||
| ScriptEngine result = | |||||
| if (languageIsJavaScript()) { | |||||
| maybeEnableNashornCompatibility(); | |||||
| } | |||||
| final ScriptEngine result = | |||||
| new ScriptEngineManager().getEngineByName(getLanguage()); | new ScriptEngineManager().getEngineByName(getLanguage()); | ||||
| if (result == null && JavaEnvUtils.isAtLeastJavaVersion("15") | if (result == null && JavaEnvUtils.isAtLeastJavaVersion("15") | ||||
| && languageIsJavaScript()) { | && 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 final static List<String> JS_LANGUAGES = Arrays.asList("js", "javascript"); | ||||
| private boolean languageIsJavaScript() { | private boolean languageIsJavaScript() { | ||||
| @@ -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")); | |||||
| } | |||||
| } | |||||
| @@ -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); | |||||
| } | |||||
| } | |||||
| @@ -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(); | |||||
| } | |||||
| } | |||||
| @@ -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"); | |||||
| } | |||||
| } | |||||