私は、私たちのアプリケーション用のパッチを作成するために内部的に書いたツールを持っています。 変更されたクラスをscmで確認し、javac
を使用してコンパイルします。
次に、作成したjarをクラスパスに追加します。 私はそれに問題があることを発見しました: クラスAでメソッドの戻り値の型を変更し、クラスBがそのメソッドを使用するとクラスAの署名が変更され、クラスBがそのメソッドを呼び出すときにNoSuchMethodError
を取得します。
しかし、私はクラス静的変数が変更された別のケースを持っています: java.lang.NoClassDefFoundError: Could not initialize class
。
原因を知っていますか?
クラスが変更されたときにどのクラスをコンパイルする必要があるかを知る方法はありますか?クラスの変更時にどのクラスをコンパイルする必要がありますか?
答えて
信頼できないと思われるソリューションを開発するために多くの努力をしているように思えます。
すべてのリリースで、アプリケーション全体をビルドします。パッチを作成するには、オリジナルの配布物と比較して、作成したクラスまたはファイルを比較します。変更されたファイルはすべて含まれます。
あなたは定数、メソッドまたはクラスを変更し、すべての結果を理解する必要はありません
- ので、これは良いです。
- 書式やコメントのような何かを変更しても、ファイルを更新する必要はありません。
- パッチの適用がまったく同じで、完全に配布されていることを確信することができます。
クラスAのシグネチャを変更した場合、このクラスを呼び出すすべてのクラスを再コンパイルする必要はありません。これらのクラスの実装を変更する必要があります。もし、クラスA、クラスBによって呼び出されたメソッドfoo()
を持っていたし、今はbar()
に社名を変更した場合
は、たとえば、あなたは、クラスBのソースコードを変更する必要がありそうでない場合、あなたはNoSuchMethodError
を取得します。
ただし、インターフェイスを変更せずにクラスAの内部実装を変更するだけで、このクラス自体以外のものを再コンパイルする必要はありません。コンパイルするときは、適切なクラスパスを作成するだけです。クラスパスには、クラスAの直接依存関係と依存関係の依存関係が含まれていなければなりません。第3レベルの依存関係(つまり、依存関係の依存関係)を含んではいけません。しかし、IMHOは、パッチをコンパイルするときにクラスパスを処理する最も簡単な方法は、既存のアプリケーションの完全なクラスパスを提供するだけです。
いくつかのシグネチャの変更があります。たとえば、戻り値の型が以前と同じ型に割り当てられている場合や、引数の型がさらに広くなっている場合など、(少なくともいくつかの)用途を単純に再コンパイルすることができます。定数の変化に似ています。 –
また、例外やエラーを引き起こすことはないが、間違った動作を引き起こすため、定数をターゲットにすることは困難です。
あなたがプリミティブ型またはString
と、その値はコンパイル時に決定することが可能であるいくつかpublic static final
フィールドを持つクラスを考えてみましょう。
public class A {
public static final String GREETING = "Hello";
...
}
別のクラスBこのフィールドにアクセスする場合、コンパイラは定数をインライン - すなわちA.GREETING
参照をその値"Hello"
に置き換えます。一定値がどこから来るのかの情報は保持されません。
今すぐトラブルが来る - あなたもそれを再コンパイルするまで、あなたができる唯一のクラス"Hi"
を言うし、再コンパイルするGREETING
の値を変更した場合、クラスBにおけるインライン値は変更されません。したがって、は、最初に他の人が既に指摘しているように、アプリケーション全体を最初から再構築することをお勧めします。
この問題を議論素晴らしい記事: http://marxsoftware.blogspot.com/2009/09/inconstant-constants-in-java.html
一部SO関連の質問:
Is Java guaranteed to inline string constants if they can be determined at compile time
- 1. 他の内部クラスを変更した場合、内部クラスをコンパイルする必要はありますか?
- 2. rubyメソッドがクラスのインスタンスメソッドを変更する必要がありますか?
- 3. カスタムArrayAdapterクラスのImageViewを変更する必要があります。
- 4. web.configの変更後にコンパイルする必要がありますか?
- 5. クラスのインスタンスにメソッドをオーバーライドする必要があります
- 6. 親クラスが子クラスを参照する必要がありますか?
- 7. 一時パスワードを変更する必要があります
- 8. RMI:再コンパイルされたimplクラスが必要な変更
- 9. PHP - クラスを使用する必要がありますか?
- 10. いつ子どものクラスをインスタンス化する必要がありますか?
- 11. クラス名は、クラス自体またはそのクラスのインスタンスを反映する必要がありますか?
- 12. 実行時にコードファーストEF4クラスをコンパイルするのに問題があります。
- 13. クラス内にクラスが存在するかどうかを確認する必要はありません/
- 14. Stringのプロトタイプを変更する必要がありますか?
- 15. クラスを変更した後にアプリケーションサーバーを再起動する必要がありますか?
- 16. CoreignでCodeigniterクラスを使用する必要があります
- 17. クラスのコンストラクタ名を大文字にする必要がありますか?
- 18. Android:ListViewアダプタをViewModelクラスの一部にする必要がありますか?
- 19. 静的ライブラリの更新時にメインアプリケーションを再コンパイルまたは再リンクする必要がありますか?
- 20. 抽象クラスの必要性はここにありますか?
- 21. プログラムカウンタは常に変更する必要がありますか?
- 22. ファイルヘッダをクラスまたは構造体にする必要がありますか?
- 23. 1つのクラスのデータベーススキーマを生成する必要がありますか?
- 24. デザイン/コンパイル時にUserControlの依存関係をどのようにする必要がありますか?
- 25. JSONP、JSONファイルを変更する必要がありますか?
- 26. your.package.namespace - 何を変更する必要がありますか?
- 27. コンパイル時にクラスを残す
- 28. 抽象クラス用のインタフェースを作成する必要がありますか?
- 29. 拡張クラスのコンストラクタを記述する必要がありますか?
- 30. 注釈の定数クラスを作成する必要がありますか?
すべてを再コンパイルする方が簡単ではありません場合、私は思ったんだけどとdiffツールを使用して、実際に変更されたバイナリファイルを探します。 –
私はこの問題のいくつかの詳細な議論を読みました。簡単な答えは、再コンパイルが必要なことを知ることは簡単ではなく、スタンドアロンのツールはありません。 Eclipseのインクリメンタル・コンパイラはこれを実行できますが、コンパイルの一部としてのみ実行できます。 @ JensSchauderの提案は良いもののようだ。 –