Reputation:
I'm trying to write an Ant build that does not require me adding Ant-plugins to Ant's lib directory, or /home/myuser/.ant/lib
, or in my Eclipse instance's ant home, etc; namely because I will eventually be building my project on a hosted Jenkins server where I do not have access to the system's Ant installation.
I'm calling this a "self-bootstrapping" build, because I use Ivy to pull down my Ant plugins at build time, and hopefully, with some proper configuration, make their tasks available to Ant dynamically.
The jist of my build (using ant-contrib plugin as an example:
<?xml version="1.0" encoding="utf-8" ?>
<project name="myapp" default="audit" basedir="."
xmlns:ivy="antlib:org.apache.ivy.ant"
xmlns:antcontrib="antlib:net.sf.antcontrib">
<!-- Build path. -->
<path id="build.path">
<fileset dir="${lib.buildtime.dir}" includes="**/*.jar"/>
</path>
<target name="bootstrap">
<taskdef resource="org/apache/ivy/ant/antlib.xml"
uri="antlib:org.apache.ivy.ant" classpathref="build.path"/>
</target>
<target name="resolve" depends="bootstrap">
<ivy:settings url="${ivy.settings.home}"/>
<ivy:cleancache/>
<ivy:resolve file="${ivy.xml}"/>
<ivy:retrieve pattern="${gen.lib.main.dir}/[artifact]-[revision].[ext]" conf="main"/>
<ivy:retrieve pattern="${gen.lib.test.dir}/[artifact]-[revision].[ext]" conf="test"/>
<ivy:retrieve pattern="${gen.lib.buildtime.dir}/[artifact]-[revision].[ext]" conf="buildtime"/>
<ivy:report todir="${gen.staging.dir}" />
<ivy:cachepath pathid="build.path" conf="buildtime"/>
</target>
<target name="taskdefs" depends="resolve">
<taskdef resource="/net/sf/antcontrib/antlib.xml"
uri="antlib:net.sf.antcontrib" classpathref="build.path"/>
<property name="fizz" value="buzz" />
<antcontrib:if>
<antcontrib:equals arg1="${fizz}" arg2="buzz" />
<antcontrib:then>
<echo message="Fizz is buzz!" />
</antcontrib:then>
<antcontrib:else>
<echo message="Fizz is not buzz!" />
</antcontrib:else>
</antcontrib:if>
</target>
</project>
When I run the taskdefs
target, instead of seeing an echoed "Fizz is buzz!" message in my Ant output, I get the following error:
BUILD FAILED
/home/myuser/eclipse/workspace/myapp/build.xml:169: Problem: failed to create task or type antlib:net.sf.antcontrib:if
Cause: The name is undefined.
Action: Check the spelling.
Action: Check that any custom tasks/types have been declared.
Action: Check that any <presetdef>/<macrodef> declarations have taken place.
No types or tasks have been defined in this namespace yet
This appears to be an antlib declaration.
Action: Check that the implementing library exists in one of:
-/home/myuser/eclipse/plugins/org.apache.ant_1.8.3.v201301120609/lib
-/home/myuser/.ant/lib
-a directory added on the command line with the -lib argument
Is what I am trying to do (avoid having to do 1 of the 3 recommended things above) impossible? If so, why? If not, what is wrong with my setup here? Thanks in advance!
Upvotes: 0
Views: 1033
Reputation: 77971
I normally create a single "boostrap" target and use this to install ivy into the "$HOME/.ant/lib" directory. See:
The following is a more complete example that does what you're trying to do:
In conclusion, it's a shame ivy is not packaged by default with ANT. If you discover your hosted service prevents you from copying files into the home directory, then perhaps the simplest thing to do is ship a copy of the ivy jar alongside your source (and enable it using a taskdef)
Use the following taskdef for ant-contrib:
<taskdef uri="antlib:net.sf.antcontrib" classpathref="build.path"/>
The homepage needs update. At some stage in the recent past the library was repackaged as an antlib.
Upvotes: 1