How do I share data between custom Ant tasks?
I wrote two different custom Ant tasks. They are trying to share data through a static member in a base class. This is not working for me.
I assume I am using static members correctly within Java. I think this is a dynamic loading issue with the Java VM. However, I am a relative newbie with Java.
Since Ant custom tasks are mapped at runtime using the taskdef
task, the Ant build engine must dynamically load this code via java.lang.reflect.Constructor.newInstance().
Is there a trick to make this work?
Note: This works fine in "regular" Java code... it is the dynamic loading of Ant that is the issue.
Example classes:
import org.apache.tools.ant.Task; public class AntCustomTaskShared extends Task { private static Integer _static_bigdata = null; public Integer get_bigdata() { if (_static_bigdata == null) { log("alloc"); // from ant Ta开发者_开发技巧sk class _static_bigdata = new Integer(0); } return _static_bigdata; } }
import org.apache.tools.ant.BuildException; public class AntCustomTask1 extends AntCustomTaskShared { public void execute() throws BuildException { Integer big_data = get_bigdata(); // "alloc" is printed // do stuff with big_data log("I'm doing big stuff"); } }
import org.apache.tools.ant.BuildException; public class AntCustomTask2 extends AntCustomTaskShared { public void execute() throws BuildException { Integer big_data = get_bigdata(); // "alloc" is printed (again) // do stuff with big_data log("I'm doing big stuff again"); } }
Example Ant build.xml:
<?xml version="1.0" encoding="UTF-8"?> <project name="MyTask" basedir="." default="init"> <target name="init" description="test the custom task" > <taskdef name="CustomTask1" classname="AntCustomTask1" classpath="C:\my_custom_ant_task_class_files" /> <taskdef name="CustomTask2" classname="AntCustomTask2" classpath="C:\my_custom_ant_task_class_files" /> <CustomTask1/> <CustomTask2/> </target> </project>
Do all of the above and you will see "alloc" logged twice. I cannot get these two custom tasks to share the "big data".
I am running ant 1.8.1 on Windows with these two env vars:
- JAVA_HOME=C:\Program Files\Java\jdk1.6.0_21
- CLASSPATH=(empty)
Hint: If you want to step into this custom task from an Ant (1.8) process, set your breakpoints here:
org.apache.tools.ant.launch.Launcher.main()
org.apache.tools.ant.UnknownElement.execute()
The solution is simple, but poorly (or not?) documented on the Ant website. (I will commit a patch to the Ant docs to correct this situation!)
I needed to use the attribute loaderref
on taskdef
nodes. The token is used to reference the ClassLoader (and share it). After, static members are shared between custom tasks correctly.
Corrected Ant build.xml:
<?xml version="1.0" encoding="UTF-8"?> <project name="MyTask" basedir="." default="init"> <target name="init" description="test the custom task" > <taskdef name="CustomTask1" classname="AntCustomTask1" classpath="C:\my_custom_ant_task_class_files" loaderref="my_shared_class_loader" /> <taskdef name="CustomTask2" classname="AntCustomTask2" classpath="C:\my_custom_ant_task_class_files" loaderref="my_shared_class_loader" /> <CustomTask1/> <CustomTask2/> </target> </project>
This is less elegant, but you could try sharing the information via the System.setProperty
and System.getProperty
calls. The ANT class loading is definitely different then a normal Java application.
精彩评论