I'm trying to use the -lib option to specify a directory containing Ant tasks. But they're not loading. For example:
$ ant -lib /path/to/libraries
Buildfile: build.xml
BUILD FAILED
/path/build.xml:3: taskdef class com.oopsconsultancy.xmltask.ant.XmlTask cannot be found
The build file contains:
<project name="test">
<taskdef name="xmltask" classname="com.oopsconsultancy.xmltask.ant.XmlTask" />
</project>
This is failing on RHEL5, but the exact same thing works on several other operating systems that I've tried.
When I add the --execdebug flag, I get this:
exec "/usr/local/jdk1.6.0_20/bin/java" -classpath "/usr/share/java/ant.jar:/usr/share/java/ant-launcher.jar:/usr/share/java/jaxp_parser_impl.jar:/usr/share/java/xml-commons-apis.jar:/usr/local/jdk1.6.0_20/lib/tools.jar" -Dant.home="/usr/share/ant" -Dant.library.dir="/usr/share/ant/lib" org.apache.tools.ant.launch.Launcher -cp "" "-lib" "lib"
Any ideas?
Others seem to have the same problem on RHEL.
One workaround suggested here is to set your jar in the taskdef like so
<taskdef name="xmltask" classname="com.oopsconsultancy.xmltask.ant.XmlTask"
classpath="xmltask.jar"/>
Also see this thread which was a corrupt ant package
Related
According to the man page of make, -n option does the following job:
Print the commands that would be executed, but do not execute them.
I am looking for an option which acts the same in Apache Ant.
Horrific, but here it is. We can hack the targets at runtime using some code inside a <script> tag*. The code in do-dry-run below sets an unless attribute on each of your targets, and then sets that property so that none of them executes. Ant still prints out the names of targets that are not executed because of an unless attribute.
*(JavaScript script tags seem to be supported in Ant 1.8+ using the Oracle, OpenJDK and IBM versions of Java.)
<?xml version="1.0" encoding="UTF-8"?>
<project default="build">
<target name="targetA"/>
<target name="targetB" depends="targetA">
<echo message="DON'T RUN ME"/>
</target>
<target name="targetC" depends="targetB"/>
<target name="build" depends="targetB"/>
<target name="dry-run">
<do-dry-run target="build"/>
</target>
<macrodef name="do-dry-run">
<attribute name="target"/>
<sequential>
<script language="javascript"><![CDATA[
var targs = project.getTargets().elements();
while( targs.hasMoreElements() ) {
var targ = targs.nextElement();
targ.setUnless( "DRY.RUN" );
}
project.setProperty( "DRY.RUN", "1" );
project.executeTarget( "#{target}" );
]]></script>
</sequential>
</macrodef>
</project>
When I run this normally, the echo happens:
$ ant
Buildfile: build.xml
targetA:
targetB:
[echo] DON'T RUN ME
build:
BUILD SUCCESSFUL
Total time: 0 seconds
But when I run dry-run, it doesn't:
$ ant dry-run
Buildfile: build.xml
dry-run:
targetA:
targetB:
build:
BUILD SUCCESSFUL
Total time: 0 seconds
Ant has no dry-run option as make or maven have. But you could run the ant file step by step it in debugging mode under eclipse.
No I belive. There is no such way by default in Ant. And many unstisfying attempts you would find on google. But I have searched once and was unsuccessful.
It would be a useful feature, but not easily implemented.
Make and ANT are architecturally quite different. ANT doesn't run external OS commands, instead, most ANT "tasks" execute within the same Java thread.
It would be possible to emulate a "dry run" as follows:
<project name="Dry run" default="step3">
<target name="step1" unless="dry.run">
<echo>1) hello world</echo>
</target>
<target name="step2" depends="step1" unless="dry.run">
<echo>2) hello world</echo>
</target>
<target name="step3" depends="step2" unless="dry.run">
<echo>3) hello world</echo>
</target>
</project>
Running ANT as follows will print the target name but won't execute the enclosed tasks:
$ ant -Ddry.run=1
Buildfile: build.xml
step1:
step2:
step3:
BUILD SUCCESSFUL
Total time: 0 seconds
Create a special target in your buildscript that does some echoing only i.e. to check whether properties, path .. are resolved correctly.
see https://stackoverflow.com/a/6724412/130683 for a similar question answered.
For checking the details of your ant installation use ant -diagnostics
I have several build files which all import the same base build file, like this:
base.xml:
<project name="base">
<!-- does not define a 'build' target -->
</project>
buildA.xml:
<project name="buildA">
<import file="base.xml" />
<target name="build">
<ant antfile="buildB.xml" target="build"
inheritall="false" inheritrefs="false" />
</target>
</project>
buildB.xml:
<project name="buildB">
<import file="base.xml" />
<target name="build">
...snip...
</target>
</project>
(Module A depends on module B.)
Now, the above calling of B's build target from buildA.xml gives the following error:
Duplicated project name in import. Project base defined first in buildA.xml and again in buildB.xml
Since both buildA.xml and buildB.xml inherit the same base.xml, this seems unavoidable.
How could I get rid of this error?
Based on sudocode's answer, I solved the problem. Because the absolute path to base.xml is different in both cases, Ant does not recognize it as the same file. Even though inheritAll is set to false, the context of the calling task is preserved and this causes the name clash.
To solve this, one can omit the name attribute from base.xml. Since Ant 1.8, the import task has an attribute as, which can be used to reference base targets when the base project is nameless. If you don't override any targets, you can use include instead of import. I'm on 1.7, so that does not help me.
For previous versions of Ant, you can go through an exec call to prevent proliferation of the Ant context entirely (then you get two running Ant instances). Better yet, find a way to import the exact same base.xml (with the same absolute path) in both files.
Are you using Ant 1.6? This resolved Ant bug looks like the same issue.
EDIT
I tried to reproduce the dir structure you refer to in your recent comment.
./base.xml
./buildA
./buildA/buildA.xml
./buildB
./buildB/buildB.xml
And amended the build files accordingly, e.g.
<project name="buildA">
<import file="../base.xml"/>
<target name="build">
<ant antfile="../buildB/buildB.xml" target="build" inheritall="false" inheritrefs="false"/>
</target>
</project>
I still get no build error for the following with ant 1.8.2 or 1.7.1:
ant -f buildA/buildA.xml build
I have a target named test and I want to do some tests.
I put here the important parts in build.xml. It includes:
<property name='lib.dir' value='lib' />
<path id='classpath'>
<fileset dir="${lib.dir}" includes="**/*.jar" />
</path>
And I have put the junit.jar and ant-junit.jar(is it a must?) in the lib directory.
However, if I run
ant test.
The output error is:
test:
BUILD FAILED
/home/xiaohan/EclipseWorkSpace/AntTest/build.xml:82: Problem: failed to create task or type junit
Cause: the class org.apache.tools.ant.taskdefs.optional.junit.JUnitTask was not found.
This looks like one of Ant's optional components.
Action: Check that the appropriate optional JAR exists in
-/usr/share/ant/lib
-/home/xiaohan/.ant/lib
-a directory added on the command line with the -lib argument
Do not panic, this is a common problem.
The commonest cause is a missing JAR.
This is not a bug; it is a configuration problem
Additionally, if I put the two jar files in /usr/share/ant/lib with the $ANT_HOME set, it still does not work.
Really thanks for any hints
In my case (using Mint, based on Debian)
sudo apt-get install ant-optional
was the only thing that worked.
The issue was solved on RHEL-based systems once ant-junit was installed:
$ sudo yum install ant-junit
<property name='lib.dir' value='lib' />
<path id='classpath'>
<fileset dir="${lib.dir}" includes="**/*.jar" />
</path>
this has nothing to do with Ant classpath itself. It is properties you can use in your tasks. You have to put jars to the suggested dirs or add command line argument.
Try running it like this:
ant -lib /path/to/the/ant-junit.jar/ test
I was seeing this message because I had missed to include the ant-junit.jar from my IDE's Classpath, e.g. in Eclipse > Right click on your project > Run as > Run Configurations.. > Classpath (tab) > Ensure the ant-junit.jar is there.
When you run JUnit tasks, you must make sure both your classpath that was used for your builds, and the path for the junit jars are added to your classpath.
I prefer to put the junit jars inside my project, so others don't have to install them in their machines for my build to work. I would install them in ${basedir}/antlib/junit
I use ${basedir}/antlib to store all the various Ant build related jars such as the Ant-Contrib jars, JaCoCo, Findbugs, etc. Since this is inside my project, a checkout will always include these jars and the build will work for everyone:
<classpath id="junit.path">
<fileset dir="${basedir}/antlib/junit"/>
</classpath>
This will create a path that contains your JUnit jars. Now to compile your junit tests:
<javac dest="${target.dir}/test-classes"
src=${src.test.java}">
<classpath refid="javac.classpath"/> <!-- Your main build classpath -->
<classpath refid="junit.path"/> <!-- Your JUnit classpath -->
<classpath path="${main.destdir}"/> <!-- These the classes you've built-->
Note that placing the JUnit jars in $ANT_HOME/lib main not work because it depends whether <javac> has includeAntRuntime set or not. It's always highly recommended not to have this set in order to make your build more platform independent.
Also remember to include that junit.path in your <junit> task too.
I wanted to have a look which system properties are set here (and to which values), so the easiest way (if not writing a new Java program here) would be adding some lines to my ant build script:
<target name="properties">
<echoproperties/>
</target>
But running ant gives my this error message:
/u/ebermann/projektoj/stackoverflow-examples/build.xml:19: Problem: failed to create task or type echoproperties
Cause: the class org.apache.tools.ant.taskdefs.optional.EchoProperties was not found.
This looks like one of Ant's optional components.
Action: Check that the appropriate optional JAR exists in
-/usr/share/ant/lib
-/u/ebermann/.ant/lib
-a directory added on the command line with the -lib argument
Do not panic, this is a common problem.
The commonest cause is a missing JAR.
This is not a bug; it is a configuration problem
Okay, so I don't panic, but wonder what to do.
I have Ant 1.7.1 here (an OpenSUSE system), and sadly no documentation for this version, and I'm not root to install either a current ant version or the documentation for the old version (I just downloaded it and it still does not say which jar file is needed here). Of the directories listed above, only /usr/share/ant/lib exists, but it contains nothing like optional.
I would want to download the necessary jar file and put it in my home directory, but where to find it? The ant download archive contains nothing like that, and I have no idea where else to search. (I did google a bit, but did not find anything.
So, can someone give me some pointers where to find the right jar file?
(I suppose the solution is quite easy, and something is just blocking my view.)
After vahapt's answer, I downloaded the file from the apache repository, and put it into the directory /u/ebermann/.ant/lib mentioned by the error message. Running ant properties again - the same result as above.
$ jar -tf /u/ebermann/.ant/lib/ant-nodeps-1.7.1.jar | grep 'EchoProperties.class'
org/apache/tools/ant/taskdefs/optional/EchoProperties.class
This looks like it should work - is the error message simply wrong?
If I put it directly into the CLASSPATH, it works:
$ CLASSPATH=/u/ebermann/.ant/lib/ant-nodeps-1.7.1.jar ant properties
Buildfile: build.xml
properties:
[echoproperties] #Ant properties
[echoproperties] #Thu Mar 10 00:46:22 CET 2011
...
[echoproperties] user.name=ebermann
[echoproperties] user.timezone=
BUILD SUCCESSFUL
Total time: 0 seconds
I don't want to change my normal CLASSPATH variable, and it should work by putting it into this directory, or did I understand something wrong?
Any ideas, or is this an ant bug?
(Also, why is this file nowhere mentioned in the ant documentation?)
Edit:
After the answer from vahapt, my ant build-file looks like this:
<project name="stackoverflow-examples" basedir=".">
<target name="echoproperties.prepare">
<available property="echoproperties.works"
classname="org.apache.tools.ant.taskdefs.optional.EchoProperties"
/>
</target>
<target name="echoproperties.init"
depends="echoproperties.prepare"
unless="echoproperties.works">
<taskdef name="echoproperties" classname="org.apache.tools.ant.taskdefs.optional.EchoProperties">
<classpath>
<fileset dir="${user.home}/.ant/lib">
<include name="ant-nodeps.jar" />
</fileset>
</classpath>
</taskdef>
</target>
<target name="properties" depends="echoproperties.init">
<echoproperties/>
</target>
</project>
This re-registers the task only if it is not already in the ant classpath. (Thus it should also work for complete ant installations which do not have this file in the home directory).
I would still say that This is not a bug; it is a configuration problem is not totally right, even more as putting the file in the indicated directory does not help.
One more interesting observation: The nodeps.jar in ${user.home}/.ant/lib (i.e. now /u/ebermann/.ant/lib/ant-nodeps.jar) is already in the class path (the one shown by ${java.class.path}, but this seems not to help for <echoproperties> to work without this taskdef.
So, this works too:
<target name="echoproperties.init"
depends="echoproperties.prepare"
unless="echoproperties.works">
<taskdef name="echoproperties"
classname="org.apache.tools.ant.taskdefs.optional.EchoProperties"
classpath="${java.class.path}" />
</target>
When you make a google search, results point to ant-nodeps-1.7.1.jar
Make sure that jar exists and you've added it into the classpath
For the second part of your question:
SOLUTION 1. You do not need to modify your CLASSPATH variable. Instead you might add it by adding the parameter -cp [JAR FILE LOCATION] (-cp is for "java" executable)
SOLUTION 2. Jar files are simply zip files, open ant-nodeps.jar copy its content to ant.jar throw away ant-nodeps.jar
SOLUTION 3. See the sample below. taskdef is a ant feature that loads a jar or a class into ClassLoader hierarchy. (You load the class before using it, works like a charm)
<?xml version="1.0" encoding="ASCII"?>
<project name="Test" default="properties" basedir=".">
<target name="properties" depends="init">
<echoproperties/>
</target>
<target name="init">
<taskdef name="echoproperties" classname="org.apache.tools.ant.taskdefs.optional.EchoProperties">
<classpath>
<fileset dir="${ant.library.dir}">
<include name="ant-nodeps.jar" />
</fileset>
</classpath>
</taskdef>
</target>
</project>
I downloaded Ant 1.7.1 and looked in the documentation that came with it. There it described echoproperties as an optional task, but didn't mention where to get the jarfile for this optional task.
Looking inside the lib folder, I discovered the ant-nodeps.jar. Apparently, it was included with Ant 1.7.1.
I would recommend that you download and install Ant 1.8. Since Ant is a Java jar file, it's not really all that difficult to install the latest and greatest version.
I looked on my Mac, and /usr/bin/ant is a link to /usr/share/ant/bin and /usr/share/ant/ is a link to /usr/share/java/ant-1.8.2. So, all I have to do is point /usr/share/ant/bin/ to the correct version of Ant.
In Ant 1.8.2, echoproperties is now a standard task.
I am getting the symlink error when i do an ant build. Searched in net and some posts suggested to download junit jar for fixing it. Downloaded junit-4.8.2.jar. Added this jar file to Classpath but still's not working. I tried to include the jar file within the build.xml but still it didn't work out.
<target name="-createDir" description="Creates logs directory">
<mkdir dir="${basedir}/${custServer}/logs" />
<symlink link="${basedir}/${custS}/application.properties" resource="${basedir}/application.properties" />
<symlink link="${basedir}/${custS}/log4j.properties" resource="${basedir}/log4j.properties" />
</target>
-createDir:
BUILD FAILED
file:/home/test1/source/teff/build.xml:28: Could not create task or type of type: symlink.
Ant could not find the task or a class this task relies upon.
ant -v
Apache Ant version 1.5.4 compiled on January 8 2005
Buildfile: build.xml
It looks like the symlink task was introduced in ant version 1.6.0.