8

クラス/ライブラリの2つのバージョンを比較して、それを呼び出すコードを壊す可能性のある変更があったかどうかを判断できるようにしたいと思います。たとえば、バージョンaのメソッドを持つクラスFooについて考えてみます。

public String readWidget(Object widget, Object helper);

バージョンbでは、メソッドは次のようになります。

public String readWidget(Object widget); //removed unnecessary helper object

またはフィールドの場合は同様のもの:

version a: public static Object sharedFoo;
version b: static Object sharedFoo; //moved to package private for version b

これらの変更を潜在的な非互換性としてフラグを立てるツールが必要です(ただし、理想的には逆ではなく、メソッドの可視性を高めます)。これで、リフレクションを介して、またはjavapからの出力を分析することでこれを実行できることがわかりましたが、既存のツール(できれば非商用)があるはずです。ですから、自分で転がしたり、不必要に車輪の再発明をしたりする前に、誰かが何かを勧めてくれるかどうかを確認したかったのです。

4

3 に答える 3

3

私は質問を理解していないかもしれませんが、コンパイラはこの問題を解決する正確なツールではありませんか?

Fooの新しいバージョンに対して使用するクラスを再コンパイルすると、Foo非互換性がある場合に非常に迅速に点灯します。

于 2011-03-24T13:44:07.873 に答える
2

GuavaはJDiffを使用してバージョンの変更を報告しますが、おそらくそれも役立つと思いますか?

于 2011-03-24T13:49:47.710 に答える
2

これがあなたが望まなかった答えです、しかし私はそれが有効な答えだと思います:

  1. APIのすべてのメソッドを呼び出す単体テストのスイートを作成します(すでにこれを持っていますよね?:-))。
  2. APIを変更するときは、APIの新しいバージョンを再コンパイルしますが、単体テストは再コンパイルしません。
  3. 「新しい」APIに対して「古い」単体テストのセットを実行します。この古い一連のテストはカナリアになり、APIのクライアントが置かれる状況を模倣します。

すべてのクライアントコードを再コンパイルするだけの最初の問題は、それが不可能な場合があることです。コードはあなたのものではないかもしれません。顧客の1人が作成したカスタムコードである可能性があり、利用できません。

クライアントコードを再コンパイルするだけの2番目の問題は、呼び出し元のコードを変更する必要がないため、コンパイルエラーが発生しない場合があることです。私は一度このような問題に遭遇しました。私はこのようなAPIメソッドを持っていました:

public void doSomething(){
}

それに対してリンクされたコードで。私はそれをこれに変更したかった:

public boolean doSomething() {
}

だから私はそうして再コンパイルしました。の最初のバージョンを呼び出したコードがdoSomething()サイレントに新しいバージョンに再リンクしたため、エラーは発生しませんでした(Javaで有効な戻り値を破棄します)。ただし、再コンパイルしたときに外部クラスのバイトコードが変更れたことはほとんど知りませんでした。APIが更新されたときにエラーが発生し始めましたが、それを使用するコードは再コンパイルされませんでした。

したがって、エラーを探す代わりに、結果としてどの外部ファイルのバイトコードが変更されたかを調べる必要がありました。その時点では、とにかくそれらを書く必要があるので、この目的のために単体テストを使用する必要があると思います。

于 2011-03-24T15:25:50.290 に答える