Running ant from a maven module containing other modules - ant

I have a directory structure like the following:
root/ui/
root/ui/pom.xml
root/ui/build.xml
root/ui/_idea/{files that I want copied are here}
root/ui/ssui/pom.xml (An inner module)
In my POM file, I'm trying to call the ant file using
<tasks>
<ant antfile="build.xml" target="copyIntelliJFiles"/>
</tasks>
And my build.xml contains
<project name="ui-parent" default="copyIntelliJFiles" basedir=".">
<target name="copyIntelliJFiles">
<copy todir="." overwrite="true">
<fileset dir="_idea"/>
</copy>
</target>
</project>
However, when I run mvn install from /root/ui, I get the following error:
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-antrun-plugin:1.6:run (create-intellij-project-files) on project ssui-parent: An Ant BuildException has occured: The following error occurred while executing this line:
[ERROR] java.io.FileNotFoundException: /root/ui/ssui/build.xml (No such file or directory)
[ERROR] -> [Help 1]
It seems to be running it from /root/ui/ssui instead of where the pom.xml is.
Debugging Done
If I change my pom.xml to instead point to ../build.xml, the error message becomes: java.io.FileNotFoundException: /root/build.xml (No such file or directory)
If I remove the sub-module definition in /root/ui/pom.xml, then the path is recognized correctly (but I need the submodules)
If I change the build.xml reference to ${basedir}/build.xml, I get the same error: java.io.FileNotFoundException: /root/ui/ssui/build.xml and it also works if I remove the sub-module
Tried the solution at Maven2 property that indicates the parent directory by creating a ui.rootdir property in both ui/pom.xml (as ${basedir}) and in ui/ssui/pom.xml (as ${basedir}/..) and referenced ${ui.rootdir}/build.xml from ui/pom.xml. Same error.
Any suggestions are welcome, but I can't restructure my directories, except for where the folder that is going to be copied lives. I did look at Usage of maven ${basedir} in multi-module setup but didn't figure out how it would solve my problem.
I created a zip file that illustrates the problem. If you run mvn install you'll notice that an error occurs from within the sub module, though it does run fine in the top level module (and copies the file in my folder)

The following solution did work for me. It is not very likely to apply to others, since it relies on an environment variable (which we already require for our build).
In root/ui/pom.xml, I added
<properties>
<ui.basedir>${env.VCLOUD_SRC_ROOT}/ui</ui.basedir>
</properties>
...
<target>
<copy todir="${ui.basedir}" overwrite="true">
<fileset dir="${ui.basedir}/_idea"/>
</copy>
<replace file="${ui.basedir}/.idea/libraries/swfaddress_2_3.xml" token="$LOCAL_REPO$" value="${local.repo}" />
</target>

Related

Ant: "Duplicated project name in import" with imported build file

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

The archive doesn't exist error when running ant jar task

I'm running an ant build file that creates a Jar. The task looks like this:
<target name="generator-app" depends="clean,compile">
<jar jarfile="${gen.App}">
<manifest>
...
</manifest>
<fileset dir="${classes}">
<include name="com/mypackage/**" />
</fileset>
<zipfileset dir="${jars}" />
</jar>
</target>
The build file runs and creates the file as expected when I run it on Linux, but fails with this error on any other platform:
BUILD FAILED /home/user/build.xml:287: the archive doesn't exist
I tried using destfile instead of jarfile, but the same result occurs. The archive does not exist indeed, but the purpose of the task is to create it.
Is there any limitation on certain platforms or any way to correct this?
Forward slashes don't seem very windowy to me :) Maybe you should convert your slashes based on your os? Do you pass this path somewhere?
I found the problem. I tried using a newer version of ant, and now the error indicates exactly what is missing (a jar to be packaged in the jar to be created).

How to solve "Cause: the class org.apache.tools.ant.taskdefs.optional.junit.JUnitTask was not found." while running "ant test"?

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.

where to find missing optional ant tasks?

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.

CreateProcess error=2 running javadoc from Ant

Can anyone tell me why I am getting this error message
Buildfile: C:\Users\Tara\workspace\Testing\build.xml
doc:
[delete] Deleting directory C:\Users\Tara\workspace\Testing\doc
[mkdir] Created dir: C:\Users\Tara\workspace\Testing\doc
[javadoc] Generating Javadoc
[javadoc] Javadoc execution
BUILD FAILED
C:\Users\Tara\workspace\Testing\build.xml:24: Javadoc failed: java.io.IOException: Cannot run program "javadoc.exe": CreateProcess error=2, The system cannot find the file specified
Total time: 206 milliseconds
when I run this in Eclipse?
<project name="SimpleBuildScript" basedir="." default="doc">
<property file="build.properties"/>
<target name="compile" description="Compiles the Task">
<delete dir="${class.dir}"/>
<mkdir dir="${class.dir}"/>
<javac srcdir="src" destdir="classes"/>
</target>
<target name="clean" description="Delete all generated files">
<delete dir="${class.dir}"/>
<delete dir="${jar.dir}"/>
</target>
<target name="doc" description="generate documentation">
<delete dir="${doc.dir}"/>
<mkdir dir="${doc.dir}"/>
<javadoc sourcepath="${source.dir}" destdir="${doc.dir}"/>
</target>
</project>
Providing you have a jdk installed and added to Eclipse:
Windows->Preferences Java->Installed
JREs->Add
You can then
Right click on build.xml
Select Run As->Ant Build... note the ellipsis!
Switch to JRE tab
Select the jdk from the list
Credit for a similar solution:
http://blog.darevay.com/2008/12/running-javadoc-ant-task-from-eclipse/
I came across the same issue and solved it by adding an additional JREs definitions under:
Windows > Preferences > Java > Installed JREs
At the time it failed, I was using Jre7 in C:\Program Files\Java\jre7 then I have added and selected Jre in C:\Program Files\Java\jdk1.7.0_07\jre.
Change Ant Config : [Edit Configuration] -> [JRE] -> Change jre to jdk
and I solve this problem
javadoc is not in the path. With newer ant you can provide attribute (executable) to specify exe location. See documentation here
Add javadoc.exe to your build path.
From the start menu, click on Control Panel > System (use classic view) to view system properties.
In the System Properties window, click on Advanced to the left.
Click on Environment Variables.
In the list of System Variables, select Path and then press the Edit button. a window that allows you to alter the value of the Path variable.
At the end of the text for the Path variable, add a semicolon and the directory path to Java (no spaces): eg. C:\Program Files\Java\jdk1.6.0_39\bin
make sure the javadoc.exe is on your path; this error usually means the ant task cannot find the executable

Resources