19

これはよくある問題です。私は 2 つのライブラリA.jarB.jarを使用していますが、これらは同じ jar の異なるバージョンに依存しています。実行時にTHIS.xxxjar
が必要だとしましょう

MY.jar   
     -> A.jar -> THIS.1.0.0.jar
     -> B.jar -> C.jar -> THIS.5.0.0.jar

特定の jar (A.jar/B.jar) をその依存関係に対してコンパイルできますが、実行時に 1 つのバージョンのみをロードする必要があります。どれ?
依存関係 (最新バージョン) を 1 つだけ読み込むということは、ライブラリに下位互換性がない場合 (下位互換性のあるライブラリはありますか?)、私のコードはおそらく実行時例外をスローすることを意味します。

とにかく、OSGi のようなものがこの問題を解決できることを知っています。
この種の問題を解決する古い方法は何だろうと思っています...

どうもありがとう

4

5 に答える 5

7

あなたが言及した「古い方法」(そしてOSGIが確かにフードの下で使用するもの)は、依存関係の両方のブランチに独自のClassLoaderをインストールすることです。これにより、たとえば、アプリケーション サーバーが同じ JVM 内で同じアプリケーションの古いバージョンと新しいバージョンの両方を実行できるようになります。

クラスローダーの階層について読んでください。

セットアップで注意が必要な部分は、両方のブランチのクラスが交わるジョイント ポイントです。どちらのブランチも、別のブランチにロードされたクラスを使用できません。これを機能させる方法は、ブート クラスローダー (JRE クラス) または MY.jar のクラスローダーによってロードされたクラスのみが両方のブランチに渡されるようにすることです。

于 2009-10-12T15:18:10.920 に答える
4

OSGi はこの問題を解決できます。OSGi バンドルは、バージョンを詳述する追加のメタデータを含む jar にすぎません。バンドルにはバージョン番号があり、依存する jar のバージョン番号 (または範囲) の詳細が示されます。

詳細については、 Javaworldの紹介記事をご覧ください。

OSGi なしでこれを解決するには、互換性のある jar でコンパイルして実行することを手動で確認する必要があります。お気づきのように、これは必ずしも簡単な作業ではありません。jar は必ずしもバージョンを識別するとは限らないため、これを行う唯一の確実な方法は、チェックサムまたは署名を記録/比較することです。

于 2009-10-12T09:50:33.237 に答える
1

KLEが述べたように、デフォルトのアプローチは新しいバージョンに依存することです。保証はありませんが、ほとんどの場合、これは機能します。おそらく(肥大化したものでありながら)最善の方法は、OSGIを使用してそれを乗り越えることです。

于 2009-10-12T09:51:29.010 に答える
1

基本的な「昔ながらの」実装のチェックアウトを参照するにはhttps://github.com/atulsm/ElasticsearchClassLoader

これにより、elasticsearch クライアントの使用の後方互換性のないバージョンを処理するためのアプローチが提供されます。

于 2016-02-13T19:20:42.000 に答える
1

多くのライブラリは下位互換性があります。すべてではありません..


古い方法では、1 つのバージョンのみに依存しようとします。

両方を同じバージョン (最新) でコンパイルする方がおそらく安全です。
少なくとも、実行時エラーではなく、コンパイル時エラーが発生します。

必要に応じて、古い依存関係で動作するライブラリを少し変更できます...
これにはソースへのアクセスが必要になります...


コンパイル時の互換性は、実行時の正しい動作も保証しないことに注意してください。これは 1 つのステップであり、次のことができます。

  • jar の新しいバージョンの WhatsNew ファイルを読む
  • 互換性の問題を報告しているユーザーをインターネットで探す
  • JUnit を書く
  • 両方の jar のコードを比較する
于 2009-10-12T09:46:38.400 に答える