私はちょうど別の* I-though-I-was-using-this-version-of-a-library-but-apparently-my-app-server-has-already-loaded-an-older-version-ofを解決しました-this-library- * issue(ため息)。
アプリケーションがすべての適切なjarファイルまたはロードされたクラスバージョンにアクセスできるかどうかを確認(または監視)するための良い方法を知っている人はいますか?
前もって感謝します!
[追記 OSGiモジュールアーキテクチャ を使い始める非常に良い理由です!]
更新: これ 記事も役に立ちました!ログファイルに書き込むことで、JBossのクラスローダーがどのクラスをロードしたかを知ることができました。
JBossを使用している場合は、特定のクラスをロードしたすべてのクラスローダーを要求できるMBean(クラスローダーリポジトリiirc)があります。
他のすべてが失敗した場合、ロードされているすべてのクラスファイルのjarの場所を出力する「Java-verbose:class」が常にあります。
Jarマニフェストに適切なバージョン情報がある場合は、バージョンを取得してテストする方法があります。マニフェストを手動で読み取る必要はありません。
Java.lang.Package 。getImplementationVersion()とgetSpecificationVersion()およびisCompatibleWith()は、探していることを実行するように聞こえます。
他の方法の中でも、this.getClass()。getPackage()を使用してパッケージを取得できます。
Java.lang.Packageのjavadocは、これらの属性の特定のマニフェスト属性名を提供しません。簡単なグーグル検索でそれが見つかりました http://Java.Sun.com/docs/books/tutorial/deployment/jar/packageman.html
Javaの現在のバージョンでは、ライブラリのバージョニングは、JARが有用なマニフェストとともに正しくパッケージ化されていることに依存するかなり厄介な用語です。それでも、実行中のアプリケーションがこの情報を便利な方法で収集するのは大変な作業です。 JVmランタイムは、何の助けにもなりません。
IvyやMavenなどの依存関係管理ツールを使用してすべての正しいバージョンをフェッチし、ビルド時にこれを適用するのが最善の策だと思います。
興味深いことに、Java 7には、まさにこの種のことのための適切なモジュールバージョン管理フレームワークが含まれている可能性があります。現時点では、それは役に立ちません。
それを確認する良い方法はないと思います。そして、私はあなたがそれをしたいかどうかわかりません。あなたがする必要があるのは、アプリサーバーのクラスローディングアーキテクチャに精通し、それがどのように機能するかを理解することです。
仕組みの簡単な説明は次のとおりです。EJBまたはWebアプリは、最初に、独自のモジュール(ejb-jarまたはwar)で宣言されたライブラリ内のクラスまたはリソースを検索します。クラスがそこに見つからない場合、クラスローダーは、宣言された依存関係(通常はejb)である親クラスローダー、またはearパッケージで宣言されたライブラリとリソースのロードを担当するアプリケーションクラスローダーに要求を転送します。 。それでもクラスまたはリソースが見つからない場合、リクエストはアプリサーバーに転送され、アプリサーバーは独自のクラスパスを検索します。
そうは言っても、Java EEモジュール(web-app、ejb)は、常に最も近いスコープにあるjarからクラスをロードすることを覚えておく必要があります。たとえば、log4jv1をでパッケージ化する場合戦争ファイル、耳のレベルでlog4j v2、アプリサーバーのクラスパスにlog4j v3を配置すると、モジュールは独自のモジュールでjarを使用します。それを取り除くと、耳のレベルで使用します。それを取り出します。モジュール間の依存関係が複雑な場合、状況はさらに複雑になります。
アプリケーションのグローバルライブラリを耳のレベルに置くのが最善です。
私のやり方よりも良い方法があるはずですが、私はこれを非常に手動の方法で行う傾向があります。
私が言ったように、それは手動ですが、それは動作します。