我有一个简单的java项目,我正在使用ant来构建。它有这两个类:
A.java:
public class A {
public static void main(String[] args) {
Integer i = 0;
B.f(i);
}
}
B.java:
public class B {
public static void f(int i) {
System.out.println("hello");
}
}
哪种方法正常:
$ ant compile
[...]
$ java -cp bin A
hello
现在,如果我将int
中的B.f
参数更改为Object
:
public class B {
public static void f(Object i) {
System.out.println("hello");
}
}
...代码重新编译好......
$ ant compile
[...]
$ java -cp bin A
Exception in thread "main" java.lang.NoSuchMethodError: B.f(I)V
at A.main(Unknown Source)
...但它在运行时崩溃了。为什么呢?
编译前的文件夹结构:
bin
build.xml
src
├── A.java
└── B.java
的build.xml:
<project>
<target name="compile">
<javac srcdir="src" destdir="bin"/>
</target>
</project>
答案 0 :(得分:2)
Ant只会编译自上次编译后没有更改的文件(除非你清理)。也就是说,只有一个文件发生了变化,另一个正在调用旧版本。如果在运行ant build之前删除所有类文件,我敢打赌它会起作用。
它在apache文档中说明了ant <javac>任务:
将递归扫描源和目标目录 要编译的Java源文件。只有没有的Java文件 相应的.class文件或类文件的旧版本 .java文件将被编译。
这些方法可以在源级别兼容,但是当编译成字节码时,它们具有其他类正在寻找的特定签名。您更改了编译的签名,因此无法找到它正在查找的方法。
------------------编辑---------------------
可以在构建中添加一个简单的干净任务:
<target name="clean"
description="clean up" >
<!-- Delete the ${build} and ${dist} directory trees -->
<delete dir="${build}"/>
<delete dir="${dist}"/>
</target>
你可以添加一个完整的重建:
<target name="fullReBuild" depends="clean compile">
</target>
然后根据需要从命令行发出ant fullReBuild
。
答案 1 :(得分:0)
默认情况下,除非文件的日期发生变化,否则ant不会重新编译任何内容。解决方案是使用<depend>任务。这使得ant在依赖项发生变化时重新编译依赖项。