0

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

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

构建.xml:

<project>
    <target name="compile">
        <javac srcdir="src" destdir="bin"/>
    </target>
</project>
4

2 回答 2

2

Ant 只会编译自上次编译以来未更改的文件(除非您清理)。也就是说,您的文件中只有一个发生了变化,而另一个正在打电话期待旧版本。如果您在运行 ant 构建之前删除所有类文件,我敢打赌它会起作用。

它在 ant <javac>任务的 apache 文档中说:

将递归扫描源目录和目标目录以查找要编译的 Java 源文件。只有没有对应 .class 文件或类文件比 .java 文件旧的 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根据需要从命令行发出。

于 2013-03-28T14:58:44.650 回答
0

默认情况下,除非文件日期更改,否则 ant 不会重新编译任何内容。解决方案是使用<depend>任务。这使得 ant 在依赖项发生变化时重新编译依赖项。

于 2013-04-11T20:59:58.490 回答