How to display the classpath build in an Ant Junit task - ant

An Ant junit task that has worked for months is suddenly failing with a NoClassDefFoundError for classes that used to be found. Is there a way to display the classpath that is built in the junit task?
<target name="basic-junit-test" description="Run a single JUnit test. ">
<junit printsummary="yes" fork="no" haltonfailure="yes">
<classpath>
<pathelement location="target/WEB-INF/lib/log4j-1.2.16.jar"/>
.
. many other pathelements
.
</classpath>
<test name="com.mycompany.command.TestUNLOCKACCOUNTCommand" outfile="${report.dir}/junit_test_results" />
</junit>
</target>

I'm a big fan of declaring my Ant paths at the top of my build and using classpath references in the various tasks.
To pathconvert task can be used to print the classpath contents as a property:
<path id="test.path">
<pathelement location="target/WEB-INF/lib/log4j-1.2.16.jar"/>
.
. many other pathelements
.
</path>
<target name="echo-path" description="Echo test path">
<pathconvert targetos="unix" property="test.path.unix" refid="test.path">
<echo message="Test path: ${test.path.unix}"/>
</target>
<target name="basic-junit-test" depends="echo-path" description="Run a single JUnit test. ">
<junit printsummary="yes" fork="no" haltonfailure="yes">
<classpath>
<path refid="test.path"/>
</classpath>
<test name="com.mycompany.command.TestUNLOCKACCOUNTCommand" outfile="${report.dir}/junit_test_results" />
</junit>
</target>
Update
Just occurred to me: an even simpler solution might be to run Ant in debug mode.

This is not really the answer to my question, Mark O'Connor and Rebse gave excellent answers, instead this is a more thorough explanation of what happened to cause me to ask the question in the first place. I had an ANT Junit task that I had used to develop about 100 controller classes. I used it for the first time in several months and every test failed with a classNotFound exception. The class that was not found was one that I was sure should be on the classpath, it was a locally created jar file that is automatically picked up for the build. I thought that somehow the classpath was at fault so I wanted to display it when a test was run.
After many attempts to figure out what was going on I put a try block around the code that was producing the classNotFound exception and I saw that the local class was not the class that was not being found. This lead me to a search of the lib directory and eventually (after about six hours) I realized that the problem was that I had replaced an older version of slf4j-api with a newer version. There was a dependency on a method that was in the older version but not in the newer.

Mark's answer just helped me, but just a quick note as I needed to close the pathconvert xml element when copying the example in the answer.
<pathconvert targetos="unix" property="test.path.unix" refid="test.path" />

Related

exist-db : Issues with ant task xdb:adduser or xdb:users : no such handler

I'm using ant scripts for initializing my exist-db.
But, I have this script below (dummy version) which is working in my local platform and not on my procution one. As I'm not the one who handle the configuration of this database, I don't know where to look in the conf to fix this.
Here is the script (which is just trying to add a new user) :
<project basedir="." default="default" name="ANTProject">
<property file="load.properties"/>
<path id="classpath.core">
<fileset dir="${path}/lib/core">
<include name="*.jar"/>
</fileset>
<pathelement path="${path}\exist.jar"/>
<pathelement path="${path}\exist-optional.jar"/>
</path>
<typedef resource="org/exist/ant/antlib.xml" uri="http://exist-db.org/ant">
<classpath refid="classpath.core"/>
</typedef>
<target name="default">
<echo message="Création du compte ${login}"/>
<xdb:adduser xmlns:xdb="http://exist-db.org/ant"
uri="xmldb:exist://${exist.uri}/exist/xmlrpc/db"
name="${login}" secret="${password}" primaryGroup="${user.group}" user="${root.login}"
password="${root.password}"/>
</target>
</project>
I get this error message :
XMLDB exception caught: No such handler: Default.setUser
I get the same thing if I use xdb:users task, but the xdb:store is working well... I'm running exist 2.1, in both my local and production plateform, and as already told, same scripts working well on local one...
I guess, it's something about the exist configuration, but I didn't find anything on enabling this tasks in the documentation.
If someone could help...
Ok, I got it.
Just for completeness, It was an issue on jar librairies. It seems I used ones which support xdb:store, but not others tasks (didn't find any release version of this)...
This ant depandancies is quite tricky and It's hard to know what your jars offer...

How to get Cobertura and Ivy working together?

I was just starting to integrate Cobertura into our main product's build process which uses Ivy as the dependency management tool. There are several libraries lib-a, lib-b and lib-c that do not have test cases and one project that depends on these libs and contains the unit and integration tests for all of these libraries.
Generally, instrumenting, running the instrumented tests and generating the Cobertura report works. However, there are several problems:
During instrumentation, there are several warnings (about 10) reported:
Problems instrumenting archive entry: a.b.c.MyClassFoo java.lang.RuntimeException: java.lang.ClassNotFoundException: a.b.c.MyClassBar
However, the reported class is exisiting. At the end of instrumentation, it reports
Saved information on 364 classes
When viewing the report, it shows all classes, but all classes of dependent libs are reported as 0% coverage.
When viewing details, it reports that no sources where found.
Now I think the problem might be, that Cobertura has problems with
- instrumenting the class files provided as jar files and
- Getting the sources from jar files
The instrumentation ant task in my build.xml does the following:
<cobertura-instrument todir="${build.dir}/instrumented-classes">
<includeClasses regex="com\.mycompany.*" />
<instrumentationClasspath>
<path refid="default.test.classpath" />
<pathelement location="${build.classes.dir}" />
</instrumentationClasspath>
</cobertura-instrument>
Should this be sufficient?
Im wondering, because of the reported warnings. All reported classes can be found within the jars.
For the second problem, I don't even know how to provide sources as jars to cobertura-report...
I tried
<cobertura-report destdir="${build.dir}/coverage">
<fileset dir="${src.dir}">
<include name="**/*.java" />
</fileset>
<ivy:cachefileset conf="runtime-test" type="sources"/>
</cobertura-report>
but it says cachefileset is not supported. I also tried using a pathid which I also can't provide in cobertura-report.
Do I have to unzip all sources before (which would be very time-consuming) and then provide them as a normal fileset?
Ok, while refactoring my Cobertura Ant tasks, I was able to solve the problem with dependency classes reported as 0% coverage.
At first my test task contained the following:
<junit printsummary="yes" haltonfailure="no">
<classpath>
<pathelement path="${build.test.classes.dir}"/>
<pathelement path="${build.dir}/instrumented-classes"/>
<pathelement path="${build.classes.dir}"/>
<path refid="default.test.classpath"/>
<path refid="cobertura.classpath"/>
</classpath>
(...)
</junit>
The problem was, that instrumenting the jar files provided by ivy results in jar files within the ${build.dir}/instrumented-classes directory. However, pathelement supposedly only looks for class files. So I added a fileset to include the instrumented jars as well:
<junit printsummary="yes" haltonfailure="no">
<classpath>
<pathelement path="${build.test.classes.dir}"/>
<pathelement path="${build.dir}/instrumented-classes"/>
<fileset dir="${build.dir}/instrumented-classes">
<include name="*.jar" />
</fileset>
<pathelement path="${build.classes.dir}"/>
<path refid="default.test.classpath"/>
<path refid="cobertura.classpath"/>
</classpath>
(...)
</junit>
The other problems still remain.

How to show Assembled Ant Classpath

I'm developing a Java project using Eclipse, and Ant as a build tool. When I run "ant all" from the command line, my project builds without any errors, but on Eclipse I get many compilation errors.
So I thought I'd copy Ant's Classpath onto my Eclipse Project's Build Path.
Is there an Ant task/command to show that? Like "ant just show me your assembled classpath" or something?
If you run Ant with the -verbose and -debug flags, you'll see all gory details of what javac is doing, including the classpath.
I would introduce a task for printing the classpath, and call that task with antcall. The classpath would be given as a parameter to that task.
You can do something like this in your target, so for example
lets say you've defined your classpath as
<path id="project.classpath">
<fileset dir="${SERVER_DEV}/classes">
<include name="*.zip"/>
<include name="*.jar"/>
</fileset>
<pathelement location="${SERVER_DEV}/3rdParty/jre/NT/1.5.0/lib/jsse.jar"/>
</path>
then you can do something like
<target name="compile" depends="init" description="Compiles All Java Sources">
<property name="myclasspath" refid="project.classpath"/>
<echo message="Classpath = ${myclasspath}"/>
<javac ...>
....
</javac>
</target>
It will print out the classpath used to run the specific target

I wonder if there is something wrong with my ant junit task

I'm writing my build.xml. However, it seems there is something go wrong with my junit task. when I run my junit task. I can build success, but the junit report only show that run 1 test with error. But I have more than 10 tests. So I wonder if there is something run with my junit task. Here is my code.
<property name="src.dir" value="src"/>
<property name="bin.dir" value="bin"/>
<property name="dest.dir" value="dest"/>
<property name="test.dir" value="test/>
<property name="lib.dir" value="lib"/>
<path id="classpath">
<pathelement location="${lib.dir}/junit-4.11.jar"/>
<pathelement location="${lib.dir}/ant-junit4.jar"/>
</path>
<target name="test" depends="compile">
<junit printsummary="yes" haltonfailure="no">
<classpath>
<pathelement location="${bin.dir}"/>
<path refid="classpath"/>
</classpath>
<formatter type="plain" usefile="false"/>
<batchtest fork="yes">
<fileset dir="${test.dir}" includes="*Test*.java"/>
</batchtest>
</junit>
</target>
I cannot figure out what is wrong so could somebody help me out?
And what is happening? Do you get any error messages?
You usually need to do the following:
Compile your normal code. The resulting *.class files should be placed inside a directory such as target/classes or build/classes. Use the destdir parameter of the <javac> task to do this.
Compile your JUnit tests.
In your classpath, you need all of the jars you needed to compile your normal classes
You need a reference to the destdir where your normal classes were compiled to.
You need the JUnit jar.
These should be compiled to a different directory from your normal jars. Normally, this is target/test-classes or build/test-classes.
Once you've compiled the JUnit tests, you may run them. You can use the <junit> task like you did.
You need to make sure that the includeantruntime parameter is set to true
You should also set fork to true.
You need the same classpath (with all three elements you had) when you compiled the test classes. More jars might be needed, but usually not.
You run the tests on the compiled JUnit test classfiles (the ones you saved to target/test-classes or build/test-classes. In your example, you're trying to run them against the source.
I use the Maven standards for my directory layout. That means my Java source is under src/main/java while my JUnit Java files are under src/test/java. Any XML or properties or other none source files needed are stored in src/main/resources. The regular source is compiled to target/classes while the Junit sources are compiled to target/test-classes.
This makes it easy to compile your code and test code separately without worrying about **/test/**, **/Test/**, **/JUnit/** exceptions in directory compiling since everything is separate.
Hope this helps.

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.

Resources