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"); | |||||
} | |||||
} |