如何强制 ant javac 任务覆盖目标目录中的 class 文件?

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

这是我想要实现的一个非常简化的版本。我有两个目录,Directory1Directory2。两个目录都包含 Java 个源文件。 Directory2 中的某些文件可以与 Directory1 中的文件具有相同的完全限定 class 名称。

使用 ant,文件被编译到名为 CompileDirectory 的目录中,首先来自 Directory1,然后来自 Directory2。我希望编译 Directory2 中的文件并覆盖 Directory1 中已编译的 class 文件。但是,ant 似乎忽略了具有相同完全限定 class 名称的 classes。

这是一个简单的例子 -

目录结构

$ 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 -buildfile build.xml 

Buildfile: ...(path).../build.xml

javac1:
    [javac] Compiling 1 source file to ...(path).../CompileDirectory

javac2:

build:

BUILD SUCCESSFUL
Total time: 0 seconds

可以看出,上面的 javac2 目标什么都不做。

当我 运行 Java 程序时,我看到 class 文件是来自 Directory1 的文件。

$ cd CompileDirectory/
$ java A 
I am class A from directory 1

有没有办法强制javac2目标中的javac任务编译Directory2中的源文件并覆盖class中的文件19=]?

这与文件的时间戳以及编译器是否认为源文件比 class 文件更新有关。

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

避免这种情况的其他可能方法是创建一个阶段目录并在那里编译 类,然后使用覆盖选项复制回原始目录。

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