7

ビルド チェーン内のいくつかの jar を再コンパイルする必要があるかどうかを判断しようとしています。たとえば、次の構造がある場合、ソースが変更されたときに jar 1 がコンパイルされ、ソースが変更されたとき、または jar 1 が再コンパイルされたときに jar 2 がコンパイルされます。 .

瓶 1:

public class Foo /* impl*/

瓶 2:

public class Bar extends Foo /*impl*/

2 つのクラス間の契約が変更されないと仮定します。抽象メソッドが追加されたり、インターフェイスにメソッドが追加されたりします。

jar 2 を再コンパイルする必要がありますか? すなわち。Foo 内のプライベート メソッドに変更が加えられた場合、Bar を再コンパイルする必要がありますか?

1つの束を変更した後、2つのクラスのバイトコードを比較してこれをテストしようとしましたが、予想どおり変更されませんでした。しかし、私の同僚は、コントラクトが変更されていないにもかかわらず、それが機能するためにすべてを再コンパイルする必要がある状況に遭遇したと主張していますが、理由が何であったかを思い出せません...それは必要ないはずです。スーパークラスに変更を加えると、2 つの間のインターフェイスが同じままであっても、サブクラスを再コンパイルする必要がある場合はありますか?

4

3 に答える 3

6

Fooオープンソース組織によってリリースされたとしましょう。Fooまた、さまざまな企業によって実装された数千のサブクラスがあります。

に何らかの変更が加えられFoo、新しいバージョンがバイナリ形式でリリースされた場合、すべての企業がコードを再コンパイルする必要がありますか? もちろん違います。(まあ、私たちは常にすべてのコードを再コンパイルしますが、必須ではありません - の新しい jar はFoo、問題を引き起こさずに簡単にドロップできます)

これはバイナリ互換性の問題であり、仕様をチェックして、変更Fooが安全であることを確認できます。http://docs.oracle.com/javase/specs/jls/se7/html/jls-13.htmlを参照してください

于 2013-02-26T19:04:40.630 に答える
3

In general case you have to recompile dependent class. However if you have not changed any methods or fields of Foo that are used by Bar you do not have to recompile Bar when Foo is changed.

For example if Foo had method protected int foo() called by Bar but you changed it signature to protected String foo() or changed its visibility to private you have to re-compile Bar. In this case Bar cannot be compiled: you have to change its code.

However if Bar does not use method foo() or if only implementation details of foo() were changed you can use Bar without re-compilation.

于 2013-02-26T19:02:48.103 に答える
2

間違いなくいいえ。jar ファイルにパッケージ化されたフレームワーク (Foo のようなコントラクトを持つ多くのクラスを含む) を使用でき、ソースからコンパイルする必要はありません。ただし、契約が直接間接的に変更されていないことを完全に確認する必要があります。間接的な変更の例:

public class Foo { //v1
    public static final int CONSTANT = 1;         
}

public class Foo { //v2
    public static final int CONSTANT = 2;         
}

public class Bar extends Foo {
    private int a(int value) {
        switch (value) {
            case CONSTANT:
                return 1;
        }
        return 2;
    }
}

クラス Bar を再コンパイルしない場合でも、値 1 が使用されます。

于 2013-02-26T19:04:36.393 に答える