I am trying to compile an adroid project using ant which contains multiple sources and external 3rd party jars.
It works fine with eclipse but i require it to run through command line using ant.
my custom_rules.xml looks like this:
<?xml version="1.0" encoding="UTF-8"?> <project name="CustomRules">
<target name="-pre-build" >
<copy todir="tmp-src" >
<fileset dir="src" includes="**" />
<fileset dir="talkAndroid" includes="**" />
<fileset dir="commonAndroid" includes="**" />
<fileset dir="cocos2dAndroid" includes="**" />
</copy>
<classpath id="classpath" description="The default classpath.">
<pathelement path="${classpath}"/>
<fileset dir="external_libs">
<include name="*.jar"/>
</fileset>
</classpath>
</target>
<target name="-post-build" >
<delete dir="tmp-src" />
</target> </project>
it isn't working for external_libs and unable to find external libraries, if I copy these jars from external_libs to libs folder ... duplicate class found errors are generated!
What should I do?
Related
On Eclipse I create war files by using ant.
The issue is that in the war file isn't included the right mypropfile.properties.
The file is properly copied, but also if I use <eclipse.refreshLocal resource="projectdir" depth="infinite"/> the old file is included. I have to refresh manually the project.
For Ant I use the "Run in the same JRE as the workspace" option.
<?xml version="1.0" encoding="UTF-8"?>
<project name="MyProject" basedir=".">
<description>
My Project
</description>
<property name="workspace.dir" value="${basedir}/../../"/>
<property name="src" value="${basedir}/../src"/>
<property name="build" value="${basedir}/../build"/>
<property name="build.classes" value="${basedir}/../build/classes"/>
<property name="lib.dir" value="${basedir}/WEB-INF/lib"/>
<property name="web.dir" value="${basedir}/WEB-INF"/>
<property environment="env"/>
<property name="real.dir" value="${basedir}/real"/>
<property name="real2.dir" value="${basedir}/real2"/>
<path id="classpath.server">
<fileset dir="${env.CATALINA_HOME}/lib" includes="*.jar"/>
<pathelement path="${build.classes}"/>
</path>
<path id="classpath.app">
<fileset dir="${lib.dir}" includes="*.jar"/>
</path>
<target name="refreshResource" if="eclipse.refreshLocal">
<eclipse.refreshLocal resource="projectdir" depth="infinite"/>
</target>
<target name="clean">
<delete dir="${build}/classes"/>
<delete dir="${build}"/>
</target>
<target name="init" depends="clean, refreshResource">
<tstamp/>
<mkdir dir="${build}"/>
<mkdir dir="${build}/classes"/>
</target>
<target name="compile" depends="init">
<javac encoding="UTF8" srcdir="${src}" destdir="${build}/classes" includeantruntime="false">
<compilerarg value="-Xlint:unchecked"/>
<classpath>
<path refid="classpath.server.bin"/>
</classpath>
<classpath>
<path refid="classpath.server"/>
</classpath>
<classpath>
<path refid="classpath.app"/>
<fileset dir="${lib.dir}" includes="*.jar"/>
</classpath>
</javac>
</target>
<target name="deleteConfig">
<delete file="${src}/mypropfile.properties"/>
</target>
<target name="real" depends="deleteConfig">
<copy file="${real.dir}/realprop.properties" tofile="${src}/mypropfile.properties"/>
</target>
<target name="real2" depends="deleteConfig">
<copy file="${real2.dir}/real2prop.properties" tofile="${src}/mypropfile.properties"/>
</target>
<target name="war-real" depends="real, compile">
<input message="Warname (without .war):" addproperty="warname"/>
<war destfile="${workspace.dir}/${warname}.war" webxml="${web.dir}/web.xml">
<fileset dir="${basedir}">
<include name="**/*.*"/>
</fileset>
<classes dir="${build.classes}"/>
</war>
</target>
<target name="war-real2" depends="real2, compile">
<input message="Warname (without .war):" addproperty="warname"/>
<war destfile="${workspace.dir}/${warname}.war" webxml="${web.dir}/web.xml">
<fileset dir="${basedir}">
<include name="**/*.*"/>
</fileset>
<classes dir="${build.classes}"/>
</war>
</target>
EDIT
The target clean was wrong, so I've corrected it, but now build failed with error
BUILD FAILED ... Reference classpath.server.bin not found.
Ant doesn't care if Eclipse has refreshed the file or not. eclipse.refreshLocal is only relevant for editors and compilers inside of the IDE.
When you run the Ant build.xml, Ant copies the file in question in the real target into the source folder and compile copies it into ${build}/classes (at least it should do that). So before you create the WAR, you must make sure the compile step has done its work (i.e. look into each file to make sure that a change is visible in each copy).
What worries my is that you use different ways to access the classes:
${build}/classes
${build.classes}
${basedir}/../build/classes
So the first step should be to define a single way to locate the folder and then use this pattern everywhere.
If that doesn't solve your problem, you need to make sure Ant notices that the file has changed. Old filesystems like FAT support only timestamps which have second resolution. If you use an USB stick for your sources, it's possible to change the file and run Ant so fast that Ant thinks the file hasn't changed.
Lastly, you need to check your classpath. If one of the JAR dependencies also contains a file called mypropfile.properties, then Java resource loading can find either version.
This and other problems made me use a different solution to configure WAR files: I pass a system property with the absolute path of the config file. That way, the WAR file doesn't change when the config changes and I have full control over which config file is loaded.
I'm trying to create an ant script to run pitest to be able to automate my mutation testing. I am getting the error:
Could not find or load main class org.pitest.mutationtest.commandline.MutationCoverageReport
This is my MutationTest.xml ant script
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project basedir="." default="mutationCoverage" name="PhoneBook">
<property name="ECLIPSE_HOME" value="C:/Program Files/eclipse/"/>
<path id="JUnit 4.libraryclasspath">
<pathelement location="${ECLIPSE_HOME}plugins/org.junit_4.11.0.v201303080030/junit.jar"/>
<pathelement location="${ECLIPSE_HOME}plugins/org.hamcrest.core_1.3.0.v201303031735.jar"/>
</path>
<path id="PhoneBook.classpath">
<pathelement location="bin"/>
<path refid="JUnit 4.libraryclasspath"/>
</path>
<path id="pit.path">
<pathelement location="lib/pitest-1.1.4.jar" />
<pathelement location="lib/pitest-ant-1.1.4.jar" />
</path>
<taskdef name="pitest" classname="org.pitest.ant.PitestTask" classpathref="pit.path" />
<target name="mutationCoverage">
<pitest
pitClasspath="PhoneBook.path"
classPath="PhoneBook.path"
targetClasses="pbook.*"
targetTests="pbook.*"
reportDir="MutationReports"
sourceDir="src"/>
</target>
</project>
What is causing this error, and how can I fix it?
Edit: I changed pitClasspath="PhoneBook.path" to pitClasspath="pit.path" and now I have a new error:
[pitest] Exception in thread "main" org.pitest.util.PitError: Unable to load class content for org.pitest.boot.HotSwapAgent
[pitest] Please copy and paste the information and the complete stacktrace below when reporting an issue
[pitest] VM : Java HotSpot(TM) 64-Bit Server VM
[pitest] Vendor : Oracle Corporation
[pitest] Version : 25.25-b02
[pitest] Uptime : 370
[pitest] Input ->
[pitest] BootClassPathSupported : true
[pitest] at org.pitest.mutationtest.tooling.JarCreatingJarFinder.classBytes(JarCreatingJarFinder.java:124)
[pitest] at org.pitest.mutationtest.tooling.JarCreatingJarFinder.addClass(JarCreatingJarFinder.java:113)
[pitest] at org.pitest.mutationtest.tooling.JarCreatingJarFinder.createJarFromClassPathResources(JarCreatingJarFinder.java:98)
[pitest] at org.pitest.mutationtest.tooling.JarCreatingJarFinder.createJar(JarCreatingJarFinder.java:74)
[pitest] at org.pitest.mutationtest.tooling.JarCreatingJarFinder.getJarLocation(JarCreatingJarFinder.java:63)
[pitest] at org.pitest.mutationtest.tooling.EntryPoint.execute(EntryPoint.java:70)
[pitest] at org.pitest.mutationtest.tooling.EntryPoint.execute(EntryPoint.java:43)
[pitest] at org.pitest.mutationtest.commandline.MutationCoverageReport.runReport(MutationCoverageReport.java:72)
[pitest] at org.pitest.mutationtest.commandline.MutationCoverageReport.main(MutationCoverageReport.java:43)
I don't know if that is better or worse, but hopefully it will be helpful in finding the problem.
A working example of a pitest ant build is provided at
https://github.com/hcoles/pitest-ant-example
I suggest you start with this and edit it until you have a working build for your codebase.
One difference I can see is that you have not included junit on the pitest path.
Your build looks a little strange as it seems to be tied to eclipse. If you are running from the IDE why not use the eclipse plugin?
Also, if you are not tied to Ant, you might want to consider maven as an alternative.
I believe much of your problem is that you're trying to use the Eclipse generated build.xml file, which doesn't contain the mutation testing target, and the target which you've added to remedy this has some errors.
I would suggest starting with the project here and attempting to understand how it works, and then changing their build.xml file to fit your needs.
However if this doesn't work, judging from your other question, the following build.xml should work if:
You divide your files into two source directories "src" and "test"
Both src and test folders contain the package "pbook"
You change the name of your tests to end in "Test" rather than begin in it
<?xml version="1.0" encoding="UTF-8"?>
<project name="Phonebook">
<property name="classOutputDir" value="build" />
<!-- classpath for pitest and any plugins -->
<path id="pitest.path">
<!-- must currently include the test library on the tool classpath. this will be fixed in a future version-->
<pathelement location="lib/junit-4.9.jar" />
<pathelement location="lib/pitest-0.33.jar" />
<pathelement location="lib/pitest-ant-0.33.jar" />
</path>
<taskdef name="pitest" classname="org.pitest.ant.PitestTask" classpathref="pitest.path" />
<target name="clean">
<delete dir="${classOutputDir}" />
</target>
<target name="compile" depends="clean">
<mkdir dir="${classOutputDir}/classes" />
<!-- Essential that line numbers and filenames are included in order for PIT to work -->
<javac srcdir="src" includeantruntime="false" debug="true" debuglevel="source,lines" destdir="${classOutputDir}/classes" />
</target>
<!-- classpath for compiling and testing the code. Note it does not include pitest and it's dependencies -->
<path id="test.path">
<pathelement location="${classOutputDir}/classes" />
<pathelement location="${classOutputDir}/test-classes" />
<pathelement location="lib/junit-4.9.jar" />
</path>
<target name="test" depends="compile">
<mkdir dir="${classOutputDir}/test-result" />
<mkdir dir="${classOutputDir}/test-classes" />
<javac includeantruntime="false" srcdir="test" destdir="${classOutputDir}/test-classes">
<classpath refid="test.path" />
</javac>
<junit>
<classpath refid="test.path" />
<batchtest todir="${classOutputDir}/test-result">
<!-- set test classes -->
<fileset dir="test">
<include name="**/*Test.java" />
</fileset>
<formatter type="xml" />
</batchtest>
</junit>
<junitreport todir="${classOutputDir}/test-result">
<fileset dir="${classOutputDir}/test-result">
<include name="TEST-*.xml" />
</fileset>
<report format="frames" todir="${classOutputDir}/test-result/report" />
</junitreport>
</target>
<!-- run pitest. note that the filters for tests and classes refer to package/class names, not source file named -->
<target name="pit" depends="test">
<path id="mutation.path">
<path refid="pitest.path"/>
<path refid="test.path"/>
</path>
<pitest pitClasspath="pitest.path" threads="2" classPath="mutation.path" targetTests="pbook.*" targetClasses="pbook.*" reportDir="pitReports" sourceDir="src" />
</target>
</project>
I'm new to Ant, so I'm looking for ideas here.
I'm looking for a way to use a different fileset per ANT target, and I'm not finding any luck reading the ANT documentation. To be concrete, here is what I have:
<fileset id="MY-FILESET-ONE" dir="..." />
<include name="**/*.java />
</fileset>
<fileset id="MY-FILESET-TWO" dir="..." />
<include name="**/*.other />
</fileset>
<target name="BASETARGET" depends="...">
<fileset refid="MY-FILESET-ONE" />
</target>
<target name="ANT-TARGET-ONE" depends="BASETARGET">
<fileset refid="MY-FILESET-ONE" />
</target>
<target name="ANT-TARGET-TWO" depends="BASETARGET" />
<fileset refid="MY-FILESET-TWO" />
</target>
What I want to do is have the fileset that the target BASETARGET uses be different depending on which target is invoked. If ANT-TARGET-ONE is invoked, use a different fileset, than if ANT-TARGET-TWO is invoked.
Here's something like I envision:
<target name="BASETARGET" depend="...">
<fileset refid="${myvar} />
</target>
<target name="ANT-TARGET-ONE" depends="BASETARGET">
<var name="myvar" value="MY-FILESET-ONE" />
</target>
<target name="ANT-TARGET-TWO">
<var name="myvar" value="MY-FILESET-ONE" />
</target>
How can I achieve this using ant? Basically I want to control which sets of my unit-tests get run depending on the target being invoked? I know properties can only be set once, so I don't think that could possibly work. I looked at the var here: http://ant-contrib.sourceforge.net/tasks/tasks/variable_task.html
however, trying to get the value out of 'myvar' like this:
<fileset refid="${myvar} />
results in a error, I'm unsure how to achieve this!
"What I want to do is have the fileset that the target BASETARGET uses be different depending on which target is invoked."
Here's a small example for that: you simply create the filesets with a given ID and refer them in your base target.
<project name="test" basedir=".">
<target name="base">
<copy todir="out">
<fileset refid="files-to-copy"/>
</copy>
</target>
<target name="def-fs-1" >
<fileset id="files-to-copy" dir="in">
<include name="a.txt" />
</fileset>
</target>
<target name="def-fs-2" >
<fileset id="files-to-copy" dir="in">
<include name="b.txt" />
</fileset>
</target>
<target name="t1" depends="def-fs-1,base" />
<target name="t2" depends="def-fs-2,base" />
</project>
I'm using Ant to build my Java application and to generate the MANIFEST.MF file automatically so it includes all the jars in my lib directory.
This seems to work but the problem is that instead of writing them as lib/some.jar, it includes my Eclipse project's name: MyProject/lib/some.jar.
This is ofcourse incorrect and causes none of the jars to be found when run as a standalone app.
Build.xml (important part is at the end):
<?xml version="1.0"?>
<project name="fidea_migration" default="dist">
<path id="compile.classpath">
<fileset dir="lib">
<include name="*.jar"/>
</fileset>
</path>
<target name="clean" description="cleaning the old deliverables">
<delete includeemptydirs="true">
<fileset dir="bin" includes="**/*"/>
</delete>
<delete includeemptydirs="true">
<fileset dir="_deliverables" includes="**/*"/>
</delete>
</target>
<target name="prepare" description="preparing the deliverables folders">
<mkdir dir="_deliverables/lib"/>
</target>
<path id="jarlib">
<fileset dir="lib/">
<include name="**/*.jar"/>
</fileset>
</path>
<manifestclasspath property="lib.list" jarfile=".">
<classpath refid="jarlib" />
</manifestclasspath>
<target name="compile" depends="clean, prepare" description="compiling java sources">
<mkdir dir="bin"/>
<javac srcdir="src/main/java" destdir="bin">
<classpath refid="compile.classpath"/>
</javac>
</target>
<target name="dist" depends="compile" description="creating binary distribution">
<copy todir="_deliverables/lib">
<fileset dir="lib"/>
</copy>
<copy todir="_deliverables">
<fileset dir="src/main/resources">
</fileset>
</copy>
<jar jarfile="_deliverables/lib/app.jar" basedir="bin">
<manifest>
<attribute name="Class-Path" value="${lib.list}"/>
</manifest>
</jar>
</target>
</project>
Example of how my Manifest looks:
Manifest-Version: 1.0
Ant-Version: Apache Ant 1.8.4
Class-Path: MyProject/lib/All-MB.jar MyProject/lib/activation.jar MyProject/lib/aspectjrt.jar
Any idea on how to fix this so it just shows xxx.jar instead of MyProject/lib/xxx.jar (so without "MyProject/lib/")?
Cheers,
Bart
manifestclasspath expects the jarfile attribute to point to the location of the JAR file (which probably doesn't exist yet, but that's fine). Since you're creating the JAR file at _deliverables/lib/app.jar and you're also copying all the lib JARs from lib to _deliverables/lib then
<manifestclasspath property="lib.list" jarfile="lib/app.jar">
<classpath refid="jarlib" />
</manifestclasspath>
should do the trick, and will create an eventual Class-Path with the right relative paths, i.e. All-MB.jar activation.jar aspectjrt.jar etc. etc.
You must set your project Dir inside your build.xml as,
<property name="projectDir" value=".." />
After this, you must try to work on everything with relative path. Currently, the reason behind problem is that the absolute path is being used.
After doing so many trial and errors on "How ANT tag works ?", I decided to write my own custom build xml file for the testcases that was written in Java and integrated with JUnit. Unfortunately my build script failing with "ClassNotFoundException". And i can see the log in generated HTML file that you get to see after running ant build script.
Please see below
<project name="WebServices integrated with JUnit and generating report with ANT" default="test" basedir="." >
<description> REST Services integration with JUnit </description>
<!-- set global properties for this build -->
<property name="project_name" value="junit"/>
<property name="src" location="src"/>
<property name="build" location="bin"/>
<property name="dist" location="dist"/>
<property name="lib" location="${user.home}/My Documents/Mr/jars"/>
<property name="reports" location="reports"/>
<!-- the names of various distributable files. NOTE: Generating distribution file "target" is not used here-->
<!-- Delete the ${build} and ${dist} directory trees -->
<target name="clean" description="clean up">
<delete dir="${build}"/>
<delete dir="${dist}"/>
<delete dir="${reports}"/>
</target>
<!-- Top level targets -->
<target name="compile" depends="init" description="compile the source code">
<javac srcdir="${src}" destdir="${build}">
<classpath>
<fileset dir="${lib}">
<include name="**/*.jar"/>
</fileset>
</classpath>
</javac>
</target>
<!-- run your tests -->
<target name="run-tests" depends="compile" description="run your test suite">
<junit printsummary="yes" haltonfailure="no" showoutput="yes">
<classpath>
<pathelement path="${build}"/>
<fileset dir="${lib}">
<include name="**/*.jar"/>
</fileset>
</classpath>
<batchtest fork="yes" todir="${reports}/raw/">
<formatter type="xml"/>
<fileset dir="${src}/Test/Services" >
<exclude name="MyFile.java"/>
<include name="**/*.java"/> // <------ IMP***: Here I am saying include .java files that are based at "${src}/Test/Services".
</fileset>
</batchtest>
</junit>
</target>
<!-- generate report on tests -->
<target name="test" depends="run-tests">
<junitreport todir="${reports}">
<fileset dir="${reports}/raw/">
<include name="TEST-*.xml"/>
</fileset>
<report format="frames" todir="${reports}/html/"/>
</junitreport>
</target>
<target name="init" depends="clean" description="initialize the build envrionment">
<!--create the time stamp -->
<tstamp/>
<!-- Create directory structure -->
<mkdir dir="${build}"/> //<----dir for class files
<mkdir dir="${lib}"/> //<----dir for all my libraries
<mkdir dir="${dist}/lib"/> //<----not used
<mkdir dir="${reports}"/>
<mkdir dir="${reports}/raw/"/>
<mkdir dir="${reports}/html/"/> //<---- it will have output reports
</target>
<target name="all" depends="clean,test">
</target>
And I guessed ANT build will pick all the source files (.java) and then it will look for all the class files that are based in build folder and started running them, but then I see "classNotFoundException" in HTML report. please see below log :
CLASS : "getlieninfo"
> java.lang.ClassNotFoundException: getlieninfo
at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
at java.lang.ClassLoader.loadClass(ClassLoader.java:423)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
at java.lang.ClassLoader.loadClass(ClassLoader.java:356)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:186)
After a while I changed .java to .class in "include" tag of my target called "run-tests" . The reason for doing this is, I thought ANT is not able to look ".java" files in source folder (src/Test/Services) hence I changed to ".class" and then modified dir attribute value in "fileset" tag to "build" so it may easily look for ".class" in BUILD folder where I will have compiled files stored. But none of my trial and error succeeded and ended up with same "classNotFoundException".
I am not sure what went wrong , can someone help me, please?
OK guys, Thanks for what ever little help I got from you. I found the problem.
I had to change include tag attribute name to "name=/Test/Services/**/*.java"/>" and modify dir attribute in fileset tag to "${src}" ; see below :
<batchtest fork="yes" todir="${reports}/raw/">
<formatter type="xml"/>
<fileset dir="${src}" >
<exclude name="MyFile.java"/>
<include name="/Test/Services/**/*.java"/> //<----this where i had to modify.
NOTE: Under src directory I have Test/Services folder which has source ".java" files in it.
</fileset>
</batchtest>
It solved my problem, but then i don't understand why ant build was not able to identify source files when i gave dir attribute as dir="${src}/Test/Services" that is in fileset tag
and kept name attribute in include tag as name="**/*.java" . My understanding is fileset tag should build the path for for the given dir path , once the path is build include tag will include or look for mentioned source files i.e. ".java" .