How to get class files even when the build fails with ant - java

I have a java project with java files more than 2500 and some of them may have compilation issue. I need to generate classfiles and route to a particular folder. Even with some of the compilation error, rest of jave turned to class files, with eclipse.
But I need to compile with build tools like ANT but it stops as build failed.
Hence no classfiles generated. Is there a way to compile and generated when project has some compilation error using ANT. The sample code is like
<?xml version="1.0"?>
<project name="REL854" basedir="." default="compile">
<target name="create" depends="delete">
<mkdir dir="src"/>
</target>
<target name="delete">
<delete dir ="src" />
<echo>exclude not working</echo>
</target>
<target name="copy" depends="create">
<copydir src="C:\ClearCase_Storage\Views\Snapshot\username_view6\opensource\Selenium\REL854\src" dest="C:\Users\username\neon\ANTBuildFor854\build\src" excludes="Samples"></copydir>
<copy todir ="C:\Users\username\neon\ANTBuildFor854\build\lib" overwrite="true">
<fileset dir="C:\ClearCase_Storage\Views\Snapshot\username_view6\opensource\Selenium\REL854\lib" ></fileset>
</copy>
</target>
<target name="compile" depends="copy"></target>
<javac failonerror="false" includeantruntime="false" srcdir="C:\Users\username\neon\ANTBuildFor854\build\src" destdir="C:\Users\username\neon\ANTBuildFor854\build\bin" includes="**/*.java"></javac>
</project>

Related

How to force ant javac task to overwrite the class file in the destination directory?

Here is a very simplified version of what I am trying to achieve. I have two directories, Directory1 and Directory2. Both directories contain Java source files. Some of the files in Directory2 can have the same fully qualified class name as the files in Directory1.
Using ant, the files are compiled to a directory called CompileDirectory, first from Directory1 and then from Directory2. I want the files in Directory2 to be compiled and overwrite the compiled class files from Directory1. However, ant seems to ignore the classes that have the same fully qualified class name.
Here's a simple example -
Directory structure
$ ls -R
.:
build.xml CompileDirectory Directory1 Directory2
./CompileDirectory:
./Directory1:
A.java
./Directory2:
A.java
build.xml
<project name="TestProject" default="build" basedir=".">
<target name="build" depends="javac1, javac2" />
<target name="javac1">
<javac srcdir="${basedir}/Directory1" destdir="CompileDirectory" includeantruntime="false"/>
</target>
<target name="javac2">
<javac srcdir="${basedir}/Directory2" destdir="CompileDirectory" includeantruntime="false"/>
</target>
</project>
Ant run
$ ant -buildfile build.xml
Buildfile: ...(path).../build.xml
javac1:
[javac] Compiling 1 source file to ...(path).../CompileDirectory
javac2:
build:
BUILD SUCCESSFUL
Total time: 0 seconds
As can be seen, the javac2 target above does nothing.
When I run the Java program, I see that the class file is the one from Directory1.
$ cd CompileDirectory/
$ java A
I am class A from directory 1
Is there a way to force the javac task in the javac2 target to compile the source file in Directory2 and overwrite the class file in the CompileDirectory?
It has to do with timestamp of files and whether the compiler thinks the source is newer than class file.
<project name="TestProject" default="build" basedir=".">
<target name="build" depends="javac1, touch2, javac2" />
<target name="javac1">
<javac srcdir="${basedir}/Directory1" destdir="CompileDirectory" includeantruntime="false"/>
</target>
<target name="touch2">
<sleep seconds="2" />
<touch datetime="now">
<fileset dir="${basedir}/Directory2" />
</touch>
</target>
<target name="javac2">
<javac srcdir="${basedir}/Directory2" destdir="CompileDirectory" includeantruntime="false"/>
</target>
</project>
Other possible way to avoid this is create a stage directory and compile the classes there and copy back to original directory using overwrite option.
<project name="TestProject" default="build" basedir=".">
<target name="build" depends="javac1, javac2, copy1" />
<target name="javac1">
<javac srcdir="${basedir}/Directory1" destdir="CompileDirectory" includeantruntime="false"/>
</target>
<target name="javac2">
<javac srcdir="${basedir}/Directory2" destdir="CompileDirectory1" includeantruntime="false"/>
</target>
<target name="copy1">
<copy overwrite="on" todir="CompileDirectory">
<fileset dir="CompileDirectory1">
<include name ="**/*.*"/>
</fileset>
</copy>
</target>

Ant task for jar

Compiling works fine, but it's not packaging into a jar file.
The final message is BUILD SUCCESSFUL with compiled classes but I cannot find a jar.
<project name="thisIsMyProject" basedir="." default="build">
.
.
.
.
.
Load Classpath and such.....
.
.
.
.
<target depends="init" name="build-project">
<javac debug="true" debuglevel="${debuglevel}" destdir="bin" includeantruntime="false" source="${source}" target="${target}">
<src path="src"/>
<classpath refid="my.classpath"/>
</javac>
</target>
<mkdir dir="build"/>
<target name="jar" description="Make My Jar File" depends="init">
<jar destfile="myFile.jar" destdir="build" basedir="bin" compress="true" />
</target>
</project>
It looks like your target names are wrong.
Your default target is "build", but you don't actually have a target called "build" - perhaps you should change the default to "jar"
Your "jar" target depends on "init", but it should probably also depend on "build-project" if you want it to compile BEFORE it packages the jar.

Refresh doesn't work before creating a war with Ant on Eclipse

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.

Ant don't start war target

I have three targets in build.xml.
There are not errors in process.
First two runned successfully, but third don't start and there are not war file in result.
This is my buid.xml
<?xml version="1.0" encoding="utf-8"?>
<project name="LoginProject" basedir="." default="compile">
<property name="src.dir" value="src"/>
<property name="classes.dir" value="build/classes"/>
<property name="war.dir" value="build/war"/>
<target name="clean">
<delete dir="build"/>
</target>
<target name="compile" depends="clean">
<mkdir dir="${classes.dir}"/>
<javac srcdir="${src.dir}" destdir="${classes.dir}" includeantruntime="false">
<classpath location="lib/myfaces-api-2.0.2.jar"/>
<classpath location="lib/servlet-api.jar"/>
</javac>
</target>
<target name="war" depends="compile">
<mkdir dir="${war.dir}"/>
<war destfile="${war.dir}/loginproject.war" webxml="web/WEB-INF/web.xml">
<fileset dir="WebContent"/>
<lib dir="lib"/>
<classes dir="${classes.dir}"/>
</war>
</target>
</project>
And this is log from command line
D:\Work\Java\AntLoginProject>ant
Buildfile: D:\Work\Java\AntLoginProject\build.xml
clean:
[delete] Deleting directory D:\Work\Java\AntLoginProject\build
compile:
[mkdir] Created dir: D:\Work\Java\AntLoginProject\build\classes
[javac] Compiling 3 source files to D:\Work\Java\AntLoginProject\build\classes
BUILD SUCCESSFUL
Total time: 1 second
What wrong i do?
I change default target to war.
But now get error.
D:\Work\Java\AntLoginProject>ant war
Buildfile: D:\Work\Java\AntLoginProject\build.xml
BUILD FAILED
D:\Work\Java\AntLoginProject\build.xml:30: Content is not allowed in trailing section.
Total time: 0 seconds
Call the build as follows:
ant war
Alternatively change the default target from "compile" to "war"
Update:
The default target is changed as follows:
<?xml version="1.0" encoding="utf-8"?>
<project name="LoginProject" basedir="." default="war">
..
Your default target is compile and you only call ant. You need to specify ant targetName if you want to run a target that's not default. In your case: ant war.

How to make a JAR file from a subset of project classes?

I have a Java project that has just about every class and package depending on everything else. I am trying to untangle it. My current idea is to extract core classes, that shouldn't depend on anything else and package them as a separate JAR that the rest of the application will use. I am using Ant and Netbeans. I am a complete Ant newbie, thought I started reading a book.
I have tried to make an Ant build file that will compile and package the core classes in a JAR. However, no matter what I do, the JAR ends up containing every application class. I am not sure if this is because some of my core classes depend on other classes, that get automatically pulled into the JAR, or because I can't get the Ant directives right. Here is my current build file:
<?xml version="1.0" encoding="UTF-8"?>
<project name="Core" default="jar">
<description>Compiles and packages Core packages</description>
<target name="init">
<mkdir dir="build/classes"/>
<mkdir dir="dist"/>
</target>
<target name="compile" depends="init">
<javac srcdir="src" destdir="build/classes"/>
</target>
<target name="jar" depends="compile">
<jar destfile="dist/core.jar" basedir="build/classes">
<zipfileset dir="build/classes" includes="core/**,xml/**,file/**,exceptions/**"/>
</jar>
</target>
</project>
Any advice?
What is the use of zipfileset entry? Following should be enough to filter in select folders to the jar.
<target name="jar" depends="compile">
<jar destfile="dist/core.jar" basedir="build/classes" includes="core/**,xml/**,file/**,exceptions/**" />
</target>

Categories

Resources