Jenkins AntExec plugin not working with ant contrib - ant

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.

Related

Ant build how to pick only modified files

I'm newly working with ANT build for middleware application source code resides inside the azure repository. I have list of packages lets say folder name called A,B,C,D each folder having the list of files its related to application.
A
B
C
D
Let say currently I have been modified single existing folder from above list (A folder alone) if i modify only A packages, and i pushed my changes into azure repo then my build pipeline started to pick all the packages by default, but i don’t want to build un-touched packages all the time (instead i want build only latest modified package alone)
project.properties
isPackages=./assets/IS/Packages
isTests=./assets/IS/Tests
Here the build.xml file
build.xml file
<?xml version="1.0"?>
<project name="testBuild" default="buildDeployTest" basedir="." >
<!-- project.properties -->
<property file="project.properties"/>
<property name="workspace.dir" location="."/>
<!-- remap the VCS structure defined in project.properties to have absolute paths -->
<property name="isProjectsDir" location="${isPackages}"/>
<property name="isTestDir" location="${isTests}"/>
<property name="buildOutputDir" value="${workspace.dir}/target/${projectName}/build"/>
<property name="repositoryName" value="${projectName}Repo"/>
<property name="testPackageNamePattern" value="*_Test"/>
<!-- Target check the modified packages -->
<target name="checkforchanges">
<srcfiles dir= "${isPackages}"/>
</target>
<target name="build" depends="checkforchanges" unless="nochanges">
<ant dir="/home/user/devteam/common/lib/ant/bin/ant" antfile="/home/user/devteam/_work/1/s/ci-assets/build.xml" target="build" inheritAll="true"/>
</target>
</project>
I have added one target name to check checkforchanges unless no changes, but I'm getting error like below.
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.

Jenkins ant plugin has wrong value for ${user.dir} working directory

I have the following build file in C:\A\B
<project name="demo" default="printCWD">
<target name="printCWD">
<echo message="user.dir=${user.dir}"/>
</target>
</project>
and run this command whilst in C:\A
ant -buildfile B\build.xml
it prints "C:\A"
But from the Ant plug-in installed on a Jenkins CI machine, which has the Buildfile setting set to "B/build.xml", it prints "/workspace/B"
Why is it on my local machine it prints the folder from which I invoked the ant command, yet on the Jenkins CI server it prints the folder that the buildfile is in?
Many thanks for any help.
Paul
It's because the Jenkins Ant plugin is changing the working directory to the directory containing the buildfile just before executing it, therefore causing user.dir to point to that directory (/workspace/B).
A look at the source code of the Ant plugin at https://github.com/jenkinsci/ant-plugin/blob/master/src/main/java/hudson/tasks/Ant.java reveals that the working directory is changed to the parent of the build file, specifically in this line (note the call to pwd(buildFilePath.getParent()):
r = launcher.launch().cmds(args).envs(env).stdout(aca).pwd(buildFilePath.getParent()).join();
Given this difference in behavior between locally and on Jenkins, I wouldn't personally rely on the user.dir property. If you want to access the current workspace of the Jenkins job, you can use the built-in environment variables provided by Jenkins:
<property environment="env"/>
<target name="printCWD">
<echo message="workspace=${env.WORKSPACE}"/>
</target>
If you don't want to explicitly reference the WORKSPACE env variable in the buildfile, you can provide a custom property to pass it from outside (with the default value set to user.dir):
<property name="root.dir" value="${user.dir}" /> <!-- default value -->
<target name="printCWD">
<echo message="root.dir=${root.dir}"/>
</target>
Then pass -Droot.dir=${WORKSPACE} in the Jenkins job.

'make -n' equivalent for ant

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

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

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