Search code examples
javaantjavac

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?


Solution

  • 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>