0

Antを使用して構築している単純なJavaプロジェクトがあります。次の 2 つのクラスがあります。

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

2 に答える 2

2

Ant は、最後のコンパイル以降に変更されていないファイルのみをコンパイルします (クリーンしない限り)。つまり、変更されたファイルは 1 つだけで、もう 1 つのファイルは古いバージョンを期待して呼び出しを行っています。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 に答える