I can get my scriptdef to run but only if I use certain names for my attributes. Apparently names like "property" and "prop1", "prop2", etc. are ok, but most other names (including "propN") are not ok. Which ones are OK and why?
This works (using attribute name prop2):
<project name="Ant Is Weird">
<property name="hostname" value="abc-de-fghijk0.lmn.opqr.stu"/>
<scriptdef name="hostSubstring" language="javascript">
<attribute name="text" />
<attribute name="prop1" />
<attribute name="prop2" />
<![CDATA[
var hn = attributes.get("text");
project.setProperty(attributes.get("prop1"), hn.replace(/[^0-9]/g,""));
project.setProperty(attributes.get("prop2"), hn.replace(/[^0-9]/g,""));
]]>
</scriptdef>
<target name="test" description="helps me learn about scriptdef">
<echo message="hostname is ${hostname}"/>
<hostSubstring text="${hostname}" prop1="firstProp" prop2="secondProp"/>
<echo message="firstProp is ${firstProp}" />
<echo message="secondProp is ${secondProp}" />
</target>
</project>
output:
$ ant test Buildfile: /apps/antTest/build.xml test: [echo] hostname is abc-de-fghijk0.lmn.opqr.stu [echo] firstProp is 0 [echo] secondProp is 0 BUILD SUCCESSFUL Total time: 0 seconds
But this fails (using attribute name propN):
<project name="Ant Is Weird">
<property name="hostname" value="abc-de-fghijk0.lmn.opqr.stu"/>
<scriptdef name="hostSubstring" language="javascript">
<attribute name="text" />
<attribute name="prop1" />
<attribute name="propN" />
<![CDATA[
var hn = attributes.get("text");
project.setProperty(attributes.get("prop1"), hn.replace(/[^0-9]/g,""));
project.setProperty(attributes.get("propN"), hn.replace(/[^0-9]/g,""));
]]>
</scriptdef>
<target name="test" description="helps me learn about scriptdef">
<echo message="hostname is ${hostname}"/>
<hostSubstring text="${hostname}" prop1="firstProp" propN="secondProp"/>
<echo message="firstProp is ${firstProp}" />
<echo message="secondProp is ${secondProp}" />
</target>
</project>
output:
$ ant test Buildfile: /apps/antTest/build.xml test: [echo] hostname is abc-de-fghijk0.lmn.opqr.stu BUILD FAILED /apps/antTest/build.xml:17: java.lang.NullPointerException at java.util.Hashtable.containsKey(Hashtable.java:335) at org.apache.tools.ant.PropertyHelper.setProperty(PropertyHelper.java:640) at org.apache.tools.ant.Project.setProperty(Project.java:538) at jdk.nashorn.internal.scripts.Script$\^eval\_.:program(<eval>:8) at jdk.nashorn.internal.runtime.ScriptFunctionData.invoke(ScriptFunctionData.java:637) at jdk.nashorn.internal.runtime.ScriptFunction.invoke(ScriptFunction.java:494) at jdk.nashorn.internal.runtime.ScriptRuntime.apply(ScriptRuntime.java:393) at jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:446) at jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:403) at jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:399) at jdk.nashorn.api.scripting.NashornScriptEngine.eval(NashornScriptEngine.java:155) at javax.script.AbstractScriptEngine.eval(AbstractScriptEngine.java:264) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.apache.tools.ant.util.ReflectUtil.invoke(ReflectUtil.java:108) at org.apache.tools.ant.util.ReflectWrapper.invoke(ReflectWrapper.java:81) at org.apache.tools.ant.util.optional.JavaxScriptRunner.evaluateScript(JavaxScriptRunner.java:103) 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:291) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) 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:390) at org.apache.tools.ant.Target.performTasks(Target.java:411) at org.apache.tools.ant.Project.executeSortedTargets(Project.java:1399) at org.apache.tools.ant.Project.executeTarget(Project.java:1368) at org.apache.tools.ant.helper.DefaultExecutor.executeTargets(DefaultExecutor.java:41) at org.apache.tools.ant.Project.executeTargets(Project.java:1251) at org.apache.tools.ant.Main.runBuild(Main.java:809) at org.apache.tools.ant.Main.startAnt(Main.java:217) at org.apache.tools.ant.launch.Launcher.run(Launcher.java:280) at org.apache.tools.ant.launch.Launcher.main(Launcher.java:109) Total time: 0 seconds
In case it matters:
$ cat /etc/redhat-release Red Hat Enterprise Linux Server release 6.8 (Santiago) $ ant -version Apache Ant(TM) version 1.8.2 compiled on December 20 2010
The attributes are lower-cased automatically. I found this out by putting
self.log(attributes);
into the script.
So if you change your script to use propn
instead of propN
it works:
project.setProperty(attributes.get("propn"), hn.replace(/[^0-9]/g,""));
This is documented in the Scriptdef
task documentation:
Note: Ant will turn all attribute and element names into all lowercase names, so even if you use
name="SomeAttribute"
, you'll have to use"someattribute"
to retrieve the attribute's value from the attributes collection.
See more on this question at Stackoverflow