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

时间:2016-03-25 15:33:44

标签: java ant javac

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

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

这是一个简单的例子 -

目录结构

$ 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

可以看出,上面的javac2目标什么也没做。

当我运行Java程序时,我发现类文件是Directory1中的那个。

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

有没有办法强制javac目标中的javac2任务在Directory2中编译源文件并覆盖CompileDirectory中的类文件?

2 个答案:

答案 0 :(得分:3)

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

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

答案 1 :(得分:0)

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

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