Apache ANT : get doesn't support the nested "header" element - ant

I am trying to use the get task in my build.xml and has target something like this
<target name="download" >
<get src="URL"
dest="dist">
<header name="aa" value="123"/>
</get>
</target>
When I execute the above target I am getting the error as
get doesn't support the nested "header" element.
I am using ant version as 1.10.1
Can someone help me to resolve this.

Related

Jenkins AntExec plugin not working with ant contrib

I have latest Jenkins running on Windows 2003 server.
Under, manage Jenkins:
I have IBM JDK set
I have ant: org.apache.ant_1.7.1.v20100518-1145 set as ant home
I have Jenkins AntExec plug in installed.
I have ant-contrib-0.6.jar inside anthome/lib.
I created a job, and added a build step, Execute Apache Ant, and I have this:
<echo> java home = ${JAVA_HOME}</echo>
<taskdef resource="net/sf/antcontrib/antlib.xml"/>
<project name="Test">
<description> Sample bulid file </description>
<target name="first">
<echo message="The first five letters of the alphabet are:"/>
<antcontrib:for list="a,b,c,d,e" param="letter">
<sequential>
<echo>Letter #{letter}</echo>
</sequential>
</antcontrib:for>
</target>
</project>
when I run build, it fails.
antexec_build.xml:
[echo] ant home = ${ANT_HOME}
[echo] java home = ${JAVA_HOME}
BUILD FAILED
C:\Program Files (x86)\Jenkins\jobs\MCSOWelcome\workspace\antexec_build.xml:13: Problem: failed to create task or type project
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.
I have tried many different things, no luck. Please suggest
AntExec comes bundled with AntContrib. You do not need to add or define it. On the contrary, to disable it, you need to open 2 Advanced... dialogs before you get the option.
What you need to do though, is use antcontrib namespace.
For example, to use for, type:
<antcontrib:for>
I ran into the same problem (I got the same error message: Problem: failed to create task or type project), although I didn't use <antcontrib:for> tag.
If you type some code to the Script source field at the Project configuration > Execute Apache Ant, the plugin doesn't use it as an entire Ant script file, but it inserts into a template script. It appears if you choose to keep the buildfile (Advanced view at Execute Ant Build step). In this case the generated antexec_build.xml Ant script will not be deleted from the Workspace of the Project after the build.
The issue is reproducable with this simple script typed in Script source:
<project>
</project>
The generated antexec_build.xml:
<?xml version="1.0" encoding="utf-8"?>
<project default="antexec_build.xml" xmlns:antcontrib="antlib:net.sf.antcontrib" basedir=".">
<!-- Read additional properties -->
<property file="antexec_build.xml.properties"/>
<!-- Make environment variables accesible via ${env.VARIABLE} by default -->
<property environment="env"/>
<target name="antexec_build.xml">
<!-- Default target entered in the first textarea - begin -->
<project>
</project>
<!-- Default target entered in the first textarea - end -->
</target>
</project>
So that, a solution would be that only include the Ant script that you intend to insert into the <target></target> tag.

Using "antcall" in included ant files

I have a shared ant script b.ant which internally use antcall. It calculates a property that the client scripts use. I use include instead of import client scripts to avoid unintentional overwriting of targets, but this gives me a problem with the antcall.
When using include all targets in b are prefixes, and depends attributes in b are updated accordingly. This is however not true for antcall. Is there a there are way to handle this, i.e. make antcall always call the "local" ant target?
I can workaround this by using import, but then I'll get all the overwrite problems. It is not possible to use depends instead of antcall.
Example files
I have two files:
a.ant
<project>
<include file="b.ant" as="b" />
<target name="test-depends" depends="b.depend">
<echo>${calculated-property}</echo>
</target>
<target name="test-call" depends="b.call">
<echo>${calculated-property}</echo>
</target>
</project>
b.ant
<project>
<target name="depend" depends="some-target">
<property name="calculated-property" value="Hello World"/>
</target>
<target name="call">
<antcall target="some-target" inheritrefs="true"/>
<property name="calculated-property" value="Hello World"/>
</target>
<target name="some-target"/>
</project>
Example output
Calling test-depend works as expected but test-call fails with this output:
b.call:
BUILD FAILED
D:\ws\rambo2\ws-dobshl\ant-test\b.ant:6: The following error occurred while executing this line:
Target "some-target" does not exist in the project "null".
Total time: 258 milliseconds
Ant is a dependency matrix specification language. Usually a bunch of <antcall/>, <ant/>, <include/> and <import/> is a sign of a poorly written build script. It's a developer trying to force Ant to act like a programming language.
For developer, it makes sense to break up a program into smaller files. Even Python and Perl scripts can benefit from this. However, breaking up an Ant build script usually causes problems. We had a developer who went through every project and broke up all the build.xml files into six or seven separate build files in order to improve the process. It basically broke the whole Ant dependency mechanism. To fix it, he then tossed in a bunch of <ant/> calls and <include> tasks. In the end, it meant that each target was called between 12 to 20 times.
Not using <import/> and <antcall/> isn't a hard and fast rule. But, I've been using Ant for years and rarely ever used these mechanisms. When I do, it's usually for a shared build file that multiple projects will use (which sounds like what you have) but instead of defining targets in my shared build file, I define macros. This eliminates the target namespace issues that you are having, and the macros work better because they act more like Ant tasks. This is especially true with the introduction of <local/> in Ant 1.8.
See if you can restructure the shared build file into using <macrodef/> instead of targets. It will make it much easier to include your shared build file.
Give a name to the <project> in b.ant and then change the target of the <antcall>:
<project name="b"> <!-- Give the project a name -->
<target name="depend" depends="some-target">
<property name="calculated-property" value="In b.depend"/>
</target>
<target name="call">
<!-- Specify the name of the project containing the target -->
<antcall target="b.some-target" inheritrefs="true"/>
<property name="calculated-property" value="In b.call"/>
</target>
<target name="some-target"/>
</project>
The result of ant -f a.ant test-call:
b.call:
b.some-target:
test-call:
[echo] In b.call
BUILD SUCCESSFUL
With the changes to b.ant, the <include> in a.ant can be simplified by removing the as attribute:
<include file="b.ant" />

Ant handle Target not found

I have created an ant project which has some targets inside. One target is called info, which displays all available targets. This target is set as the default:
<project name="XXX" basedir="." default="info">
Now I want this target to be called in case of target not found:
Target "infp" does not exist in the project "XXX"
I need this in case the user calls a target that doesn't exist. Then I want the info to be displayed, so that he sees all the available options.
Thanks
ANT does not support this functionality. The "default" target is called if no target is specified on the command line.
Instead I would suggest making your build self describing and teaching your users about ANT
's -p option.
Example
The following build file:
<project name="demo" default="welcome">
<description>
The purpose of this build file is to explain how one
can make an ANT file self describing
</description>
<target name="welcome" description="Print a hello world message">
<echo message="hello world"/>
</target>
<target name="do-somthing" description="Print a dummy message">
<echo message="hello world"/>
</target>
<target name="do-somthing-silent">
<echo message="hello world"/>
</target>
</project>
Can describe itself as follows:
$ ant -p
Buildfile: /home/mark/build.xml
The purpose of this build file is to explain how one
can make an ANT file self describing
Main targets:
do-somthing Print a dummy message
welcome Print a hello world message
Default target: welcome

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

Is there a way to pass parameters into a ant task command?

I use Ant to build my Android application. I want to be able to do this:
ant debug android-market; //build the debug version for android-market;
ant debug motorola-market; //Builds debug version for motorola-market;
ant release android-market; //etc.
Is there a way to detect that "android-market" parameter from within my custom ant debug/release task?
I would prefer not to use Dparam=value, since that is less clean looking.
This syntax is used to invoke multiple targets at once. So you could perhaps use
ant android-market debug
and make the android-market target set a property used in the debug target to identify which version to build:
<project basedir="." default="debug">
<target name="android-market">
<property name="market" value="android"/>
</target>
<target name="debug">
<echo message="debugging for the following market : ${market}"/>
</target>
</project>
> ant android-market debug
> android-market:
> debug:
> [echo] debugging for the following market : android
I would prefer not to use -Dparam=value, since that is less clean looking.
I think you should get over your preferences. But add a 'help' target that describes the parameters accepted by the other targets.
JB's answer totally worked but I wanted to find a way to have a default. I found an answer to that here by someone named Mike Schilling: http://www.velocityreviews.com/forums/t137033-is-it-possible-to-alter-ant-properties-after-theyve-been-initialized.html
So I ended up having something like this:
<project basedir="." default="debug">
<target name="set-defaults">
<property name="market" value="android"/>
</target>
<target name="motorola-market">
<property name="market" value="motorola/>
</target>
<target name="debug" depends="set-defaults">
<echo message="debugging for the following market : ${market}"/>
</target>
</project>
So you could do ant debug for android or ant motorola-market debug for motorola.

Resources