How to show Assembled Ant Classpath - ant

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

Related

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.

How to compile NSIS script using ant?

I have created NSIS script for my java project.I have installed nsis plugin in my eclipse.using plugin I have created nsi file.Now i want to compile the nsi file.I have try to using Ant in eclipse.
<?xml version="1.0" encoding="UTF-8"?>
<project name="test" default="nsis" basedir=".">
<property name="build.path" value="build"/>
<property name="deploy.dir" value="/opt/test"></property>
<path id="library.classpath">
<fileset dir="lib">
<include name="nsisant-1.2.jar"/>
</fileset>
</path>
<target name="nsis" description="compile nsis script">
<mkdir dir="${build.path}/nsis"/>
<nsis script="setup.nsi">
<classpath refid="library.classpath"/>
</nsis>
</target>
</project>
But it throws following error.
BUILD FAILED
build.xml:12: Problem: failed to create task or type nsis
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 dont know why this happen?? How to compile nsi file using ant? or Is there any other way there to compile without using ant?
Using a dedicated nsis task seems to be the best way, but maybe not the simplest. I just execute makensis.exe using such syntax:
<exec executable="C:\Program_Files\NSIS\makensis.exe" failonerror="true" >
<!-- providing some nsis definitions -->
<arg value="/DPROJECT_NAME=${ant.project.name}"/>
<!-- passing the script -->
<arg value="${basedir}\raport.nsi"/>
</exec>
As for your second question: yes, you can compile nsis script without ant. For example:
C:\Program_Files\NSIS\makensis.exe /DPROJECT_NAME=this-project my-script.nsi
Being on Linux you also should have makensis somewhere.
The PROJECT_NAME stuff is my customization. In simplest case you don't supply any definitions, omitting that part.
Do you use the NSIS Ant Task from the Nsis Ant Sourceforge project? Once installed, you can use it as
<taskdef name="nsis" classname="net.sf.nsisant.Task">
<classpath location="nsisant-{version}.jar">
</taskdef>

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.

CreateProcess error=206, The filename or extension is too long

I'm trying to call Findbugs via Ant, but receiving this error:
Cannot run program "C:\Program Files (x86)\Java\jre6\bin\javaw.exe" (in
directory "H:\Users\MyName\workspace\MyProject"):
CreateProcess error=206, The filename or extension is too long
How can I fix this? o.O
I had the same problem.
I used
<fileset dir="${basedir}/build">
<include name="**/*.class"/>
</fileset>
inside findbugs target and it seems that there is too much .class files to be passed to findbug (?via command line?) because when I used
<fileset dir="${basedir}/build/com/domain/package">
<include name="**/*.class"/>
</fileset>
that had low number of classes, the error was gone.
So, I solved the problem by making one jar file and feeding it to findbugs target with
<findbugs home="${findbugs.home}">
...
<class location="${basedir}/targets/classes-to-analyze.jar"/>
</findbugs>
I think one of the effective file paths are really long when java tries to compile clases.
One worth try is to put codebase in a directory such as C:\MyProject instead of something like C:\Users\MyName\workspace\MyProject
To solve this issue you need to generate a manifestclasspath and a pathing jar.
First Generate your classpath.
<path id="javac.path">
<fileset dir="lib/" includes="**/*.jar"/>
</path>
Next Generate your manifestclasspath
<target name="generate-manifest-classpath">
<manifestclasspath property="manifest.classpath" jarfile="pathing.jar">
<classpath refid="javac.path"/>
</manifestclasspath>
<jar destfile="pathing.jar" basedir="${the location of your build classes}">
<manifest>
<attribute name="Class-Path" value="${manifest.classpath}"/>
</manifest>
</jar>
<path id="javac.classpath">
<pathelement path="pathing.jar"/>
</path>
</target>
Next Implement your Manifestclasspath
<javac srcdir="${foo.dir}" destdir="${bar.dir}"
<classpath refid="javac.classpath"/>
</javac>
This will solve the 206 error message if implemented correctly.
I had the same error on IntelliJ while starting debug mode only. To fix is I've changed:
Run > Edit Configurations > "Configuration" tab > Shorten command line
to "JAR-manifest"

How do I pass an argument to an Ant task?

I'm not very good with Ant, but we're using it as a build tool. Right now, we can run "ant test" and it'll run through all the unit tests.
However, I'd love to be able to do something like ant test some_module and have it accept some_module as a parameter, and only test that.
I haven't been able to find how to pass command line args to Ant - any ideas?
One solution might be as follows. (I have a project that does this.)
Have a separate target similar to test with a fileset that restricts the test to one class only. Then pass the name of that class using -D at the ant command line:
ant -Dtest.module=MyClassUnderTest single_test
In the build.xml (highly reduced):
<target name="single_test" depends="compile" description="Run one unit test">
<junit>
<batchtest>
<fileset dir="${test.dir}" includes="**/${test.module}.class" />
</batchtest>
</junit>
</target>
You can also define a property with an optional default value that can be replaced via command line, e.g.
<target name="test">
<property name="moduleName" value="default-module" />
<echo message="Testing Module: ${moduleName}"/>
....
</target>
and run it as:
ant test -DmoduleName=ModuleX
What about using some conditional in your test target and the specifying -Dcondition=true?
<target name="test" depends="_test, _test_if_true>
...
</target>
<target name="_test_if_true" if="condition">
...
</target>
<target name="_test" unless="condition">
...
</target>
Adapted a bit from the ant faq.
You can define a property on commandline when invoking ant:
ant -Dtest.module=mymodulename
Then you can use it as any other ant property:
...
<fileset dir="${test.dir}" includes="**/${test.module}.class" />
...
Have a look at Ant's manual.
I tried the solutions posted here for the very same original question. Yes just use ant -D<arg_name>. THe -D is a "keyword" I guess. I'm no ant expert and have not read the manuals in detail. Then inside the ant XML files can be accessed like: ${arg_name}
For instance you can have an argument name like: arg.myarg, so in XML ${arg.myarg}.
Ant really doesn't have parameters_ for the build file. I can think of a few ways to do this:
Use a special target to specify the tests. You can use the <for/> task from AntContrib to allow you to specify multiple tests. You'll need to download the Ant-Contrib jar file. I recommend placing it inside your project under the `${basedir}/antlib/antcontrib" directory. That way, when others checkout your project, they get the needed Ant-Contrib jar file.
<property name="antlib.dir" value="${basedir}/antlib"/>
<property name="antcontrib.dir" value="${antlib}/antcontrib"/>
<!-- Set up the ant contrib tasks for your use -->
<taskdef resource="net/sf/antcontrib/antlib.xml">
<classpath>
<fileset dir="${antcontrib.dir}"/>
</classpath>
</taskdef>
<target name="select-test"
description="Select the tests to run"
depends="test-compile"
if="junit-tests">
<for parameter="module"
list="${junit-tests}"
delimiter=" ">
<sequential>
<junit
fork="true"
...>
<batchtest todir="$target/unit-tests">
<fileset dir="${test.destdir}">
<include name="**/#{module}.class"/>
</fileset>
</junit>
</sequential>
</for>
</target>
You cab now run multiple tests like this:
$ ant -D"test-one test-two test-three" select-test
You could try this to access one target at a time. Add these lines to your build.xml file :
<project name="whatever" default="default">
<input message="Please select module:" addproperty="mod" />
<target name="default" depends="${mod}/>
...
</project>
This allows you to enter the module you want to execute and execute that itself instead of running the whole build.xml
You might need to make a few more changes to your build.xml for this to work perfectly.
For the arguments , there is Facility called property. You need to set the property. As in ANT plain arguments is taken as target name.
Lest say you have two modules in your project ModuleX and ModuleY where ModuleX has 2 testcases to run and ModuleY with 10 testcases.
You could do something like this :
ant runTestsOnModule -Dtestmodule="ModuleX"
OR to test all modules by calling
ant tests
<target name="runTestsOnModule">
<antCall target="testcase${testmodule}"/>
</target>'
<! -- run single module -->
<target name="runTestsOnModule">
<antCall target="testcase${testmodule}"/>
</target>
<!--run all tests-->
<target name="tests">
<antcall target="testcaseModuleX">
<antcall target="testCaseModuleY">
</target>
<target name="testcaseModuleX">
..run junit task to call 2 testcase
</target>
<target name="testcaseModuleY">
....run junit task to call 10 testcase
</target>

Resources