testNG taskdef definition in Ant using Maven dependencies - ant

I am trying to use Ant and Maven to build a project. I am using testNG for test units. As stated here ( http://testng.org/doc/ant.html ) I have defined the taskdef as follow:
<taskdef resource="testngtasks" classpath="testng.jar"/>
in Ant.
In Maven I have added the following (as stated here: http://testng.org/doc/maven.html)
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>6.2</version>
</dependency>
Maven is getting the files from maven repository and I have checked the location under /.m2. Now that I am getting the testNG from maven, I should change the taskdef in ant to use this new one in Maven repository. I am not sure how to do that. I have tried the following:
<taskdef resource ="testngtasks" classname="org.testng" />
and
<taskdef resource ="testngtasks" classname="org.testng" classpathref="maven.compile.classpath"/>
and
<taskdef resource ="testngtasks" />
but no success, the second one complains that I shouldn't use classpathref and the first one says that I should specify class. The third one is working kind of, but not completely. It is going thorugh and I guess it passes the taskdef step but it is not executing the tests. Part of the Ant (for third one):
<taskdef resource="testngtasks" />
<target name="test" depends="compile">
<echo message="running tests" />
Part of the Ant output: (note that the echo executed, it is somehow passed the taskdef step)
compile:
[javac] /home/shahin/Files/Development/Ant/ServiceEJBSample3/build-testNG.xml:31: warning: 'includeantruntime' was not set, defaulting to build.sysclasspath=last; set to false for repeatable builds
test:
[echo] running tests
BUILD FAILED
/home/shahin/Files/Development/Ant/ServiceEJBSample3/build-testNG.xml:84: Problem: failed to create task or type testng
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 am not sure how to use testNG library in Maven repository to define ( taskdef ) the testngtasks in Ant. Any insights would be highly appreciated

try placing a pathelement property in for the classpath of your taskdef like:
<taskdef resource="testngtasks">
<classpath>
<pathelement path="[path to]/testng.jar"/>
</classpath>
</taskdef>
first hardcode the path for pathelement to make sure it's working for you.

I got it to work by using the following taskdef:
<taskdef resource="testngtasks" classpath="./lib/testng-6.2.jar"/>
When Maven retrieves the jar it will not be named testng.jar. So you will need to rename it to the appropriate jar and update the path to jar.

Related

ant failed when building project from source

The below is the code in build.xml file throwing error. I googled and found some solutions like.. add ant contrib jar file to resolve the issue. Even after adding the jar file also facing same issue. Please see the below code.
<target name="copyHtdocs" depends="init">
<export srcUrl="${svn.htdocs.url}" revision="HEAD" destPath="${htdocs.dir}" />
<export srcUrl="${svn.htdocs.url}" destPath="${htdocs.dir}"/>
</target>
Added Ant-contrib jar file:-
<taskdef resource="net/sf/antcontrib/antcontrib.properties">
<classpath>
<pathelement location="${libs.dir}/ant-contrib-0.6.jar" />
</classpath>
</taskdef>
Error:-
C:\source\xxxx\xxxx\build.xml:156: Problem: failed to create task or type export
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.
"export" is not a task that is part of the ant-contrib extension
http://ant-contrib.sourceforge.net/tasks/tasks/
I suspect you're trying to export a git repo so I would suggest using this ANT task, instead:
http://subclipse.tigris.org/svnant/svntask.html#export

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.

Compiling a build.xml file using Ant

I recently installed Ant 1.8.4 and JasperReports 4.6.0 on my Ubuntu machine.
The following environmental variables were set on my account:
PATH=$PATH:/opt/ant/bin
export PATH
export ANT_HOME=/opt/ant
export JAVA_HOME=/usr/lib/jvm/java-6-openjdk-amd64
When I try to run a demo build file in the JasperReports demo samples directory using the command ant I get the following error:
Buildfile: build.xml
BUILD FAILED
/opt/jasperreports-4.6.0/demo/samples/antcompile/build.xml:3: The following
error occurred while executing this line:
jar:file:/opt/ant/lib/ant.jar!/org/apache/tools/ant/antlib.xml:37: Problem: failed to create task or type componentdef
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.
Any help in solving this problem will be super helpful.
The snippet of build.xml file:
<project name="antcompile" default="test" basedir=".">
<description>Shows how multiple JRXML files can be compiled in batch mode using ANT.</description>
<path id="classpath">
<pathelement location="../../../build/classes"/>
<fileset dir="../../../lib">
<include name="**/*.jar"/>
</fileset>
</path>
<path id="runClasspath">
<path refid="classpath"/>
<pathelement location="../../fonts"/>
<pathelement location="./build/classes"/>
</path>
<taskdef name="jrc" classname="net.sf.jasperreports.ant.JRAntCompileTask">
<classpath refid="classpath"/>
</taskdef>
<target name="javac" description="Compiles the Java source files used in the report designs.">
<mkdir dir="./build/classes"/>
<javac srcdir="./src" destdir="./build/classes" debug="true" optimize="false" deprecation="false"/>
</target>
<target name="compile1" description="Compiles report designs specified using the "srcdir" in the <jrc> tag."> <!-- 27 row # -->
<mkdir dir="./build/reports"/>
<jrc
srcdir="./reports"
destdir="./build/reports"
tempdir="./build/reports"
keepjava="true"
xmlvalidation="true">
<classpath refid="runClasspath"/>
<include name="**/*.jrxml"/>
</jrc>
</target>
This Ant script is using custom task jrc.
As you can see from the snippet below (this is build.xml file from the jasperreports-4.6.0/demo/samples/antcompile folder), this task's definition refers the classpath from the same build file.
<path id="classpath">
<pathelement location="../../../build/classes"/>
<fileset dir="../../../lib">
<include name="**/*.jar"/>
</fileset>
</path>
...
<taskdef name="jrc" classname="net.sf.jasperreports.ant.JRAntCompileTask">
<classpath refid="classpath"/>
</taskdef>
You should check the ../../../build/classes folder (in JasperReports package's folder structure which contains samples) - the net.sf.jasperreports.ant.JRAntCompileTask class must be there.
In other words you should put this class (or jasperreports-4.6.0.jar) to the classpath (path id="classpath").
Another probable source of your problem is the version of Ant package.
You can read about Project#createTask complains it wouldn't find task componentdef issue on Ant's bugtracker and project.createTask() not working with ant-1.8.2 post.
I made it work by changing the following element in my CLASSPATH, /opt/jasperreports-4.6.0/lib/ant-1.7.1.jar to /opt/ant/lib/ant.jar.
Thanks to Alex for posting the helpful links!
Anjan
You're going have to help us out a bit here...
Are you building JasperReports-4.6.0? Or, are you using JasperReports as part of your build.xml? Is this a test build.xml demoing JasperReports?
The error says Check that any custom tasks/types have been declared, so what is the Ant task in line #37? Is there a in the build.xml? Does it have a classpath defined? If you have a taskdef, please let us see what it is, and what the custom task is.
I'm downloading iReport to see if I can figure out what you're doing, but it's taking 15 minutes. I bet you're supposed to put some jar into $ANT_HOME/lib. Maybe that JasperReports or iReport jarfile.
As soon as I can download iReport and see what you're talking about, I'll update my answer.
Meanwhile, include the relevant code around line #35 in your build.xml and the taskdef task in your build.xml.
Finished downloading iReport and there is no build.xml file in it. You're going to have to post your code, so we can look at it.
Again, my assumption is that there's some jar file that they assumed you'd stick in /opt/ant/lib and didn't.

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

How can I specify the path of a JAR in an ant buildfile?

I am executing lot of scp and sshexec and other remote commands from an ant build script. These commands don't work if jsch.jar isn't in the ant lib directory. To make it work, I copied the JAR into the ant lib directory, but this is not a good solution, as anyone else wanting to run the script would have to do the same thing. To run the ant target from Teamcity, we will have to explicitly set the path of the lib file.
Is there a way I can specify the path of the JAR in the ant build XML itself?
Thanks all for your answers. I am managed to get it work with classloader task. This is what I did.
<project basedir="." >
<property environment="env"/>
<taskdef resource="net/jtools/classloadertask/antlib.xml">
<classpath>
<fileset dir="${basedir}/lib" includes="ant-classloader*.jar"/>
</classpath>
</taskdef>
<!--Add JSCH jar to the classpath-->
<classloader loader="system">
<classpath>
<fileset dir="${basedir}/lib" includes="jsch*.jar"/>
</classpath>
</classloader>
<target name="Test">
<scp todir="user1:pass1#server1:/tmp" trust="true" >
<fileset dir="dir1">
<include name="test.txt" />
</fileset>
</scp>
</target>
</project>
As you can see here, I didn't have to give any dependant target for my "Test" target, it just works. It uses classloader, which appends jsch.jar to the system classloader.
One possible work around would be to use the -lib command line option to tell ant where to look for additional jars. Perhaps you could create a wrapper script that calls ant with this option set.
Another way would be to move the ant-jsch.jar file (this is the jar that comes with ant that defines the tasks, not the jsch.jar file you need to download separately) out of your ant lib directory, and create a taskdef for your ssh task separate to the built in one, then set the classpath for this task to the jsch.jar and the ant-jsch.jar:
<taskdef name="sshexec"
classname="org.apache.tools.ant.taskdefs.optional.ssh.SSHExec">
<classpath>
<pathelement location="jsch-0.1.44.jar"/>
<pathelement location="ant-jsch.jar" />
</classpath>
</taskdef>
I'm not sure this will help you though, since it also involves making changes to the lib directory.
As far as I'm aware, it's not currently possible to specify the extra jars required for the built in tasks in the build file itself in general. There are some special cases, like junit for instance.
To ensure your build is more cross platform I'd suggest using dependency management. The ivy plug-in can automatically install the version of your build's plugin at build-time.
This approach means the last jar you'll ever need to install into your ANT lib is ivy-2.2.0.jar :-)
First declare your project's dependencies in the file ivy.xml
<ivy-module version="2.0">
<info organisation="com.myspotontheweb" module="demo"/>
<configurations>
<conf name="anttask" description="Jars implementing ANT tasks"/>
</configurations>
<dependencies>
<dependency org="com.jcraft" name="jsch" rev="0.1.42" conf="anttask->default"/>
</dependencies>
</ivy-module>
Within your build.xml run ivy and use it to populate a custom classpath based on the ivy configuration:
<target name='init' description='Resolve project dependencies and set classpaths'>
<ivy:resolve/>
<ivy:cachepath pathid="anttask.path" conf="anttask"/>
</target>
Finally, elsewhere in your build declare your ANT tasks using the class path now automatically populated by ivy.
<target name='dosomething' depends="init">
<taskdef name="sshexec"
classname="org.apache.tools.ant.taskdefs.optional.ssh.SSHExec"
classpathref="anttask.path"/>
..
..
</target>
This approach works for all ANT plug-ins, most of which are available in the central Maven repository. The second benefit is that it's easy to upgrade the plug-in versions across all builds.

Resources