使用ant重新编译会导致代码在运行时崩溃?

时间:2013-03-28 14:56:01

标签: java ant compilation

我有一个简单的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>

2 个答案:

答案 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在依赖项发生变化时重新编译依赖项。