web-dev-qa-db-ja.com

クラスローダーの問題-ロードされているライブラリバージョン(jarファイル)を確認する方法

私はちょうど別の* 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のクラスローダーがどのクラスをロードしたかを知ることができました。

27
Johan Pelgrim

JBossを使用している場合は、特定のクラスをロードしたすべてのクラスローダーを要求できるMBean(クラスローダーリポジトリiirc)があります。

他のすべてが失敗した場合、ロードされているすべてのクラスファイルのjarの場所を出力する「Java-verbose:class」が常にあります。

18
Tom

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

5
John M

Javaの現在のバージョンでは、ライブラリのバージョニングは、JARが有用なマニフェストとともに正しくパッケージ化されていることに依存するかなり厄介な用語です。それでも、実行中のアプリケーションがこの情報を便利な方法で収集するのは大変な作業です。 JVmランタイムは、何の助けにもなりません。

IvyやMavenなどの依存関係管理ツールを使用してすべての正しいバージョンをフェッチし、ビルド時にこれを適用するのが最善の策だと思います。

興味深いことに、Java 7には、まさにこの種のことのための適切なモジュールバージョン管理フレームワークが含まれている可能性があります。現時点では、それは役に立ちません。

3
skaffman

それを確認する良い方法はないと思います。そして、私はあなたがそれをしたいかどうかわかりません。あなたがする必要があるのは、アプリサーバーのクラスローディングアーキテクチャに精通し、それがどのように機能するかを理解することです。

仕組みの簡単な説明は次のとおりです。EJBまたはWebアプリは、最初に、独自のモジュール(ejb-jarまたはwar)で宣言されたライブラリ内のクラスまたはリソースを検索します。クラスがそこに見つからない場合、クラスローダーは、宣言された依存関係(通常はejb)である親クラスローダー、またはearパッケージで宣言されたライブラリとリソースのロードを担当するアプリケーションクラスローダーに要求を転送します。 。それでもクラスまたはリソースが見つからない場合、リクエストはアプリサーバーに転送され、アプリサーバーは独自のクラスパスを検索します。

そうは言っても、Java EEモジュール(web-app、ejb)は、常に最も近いスコープにあるjarからクラスをロードすることを覚えておく必要があります。たとえば、log4jv1をでパッケージ化する場合戦争ファイル、耳のレベルでlog4j v2、アプリサーバーのクラスパスにlog4j v3を配置すると、モジュールは独自のモジュールでjarを使用します。それを取り除くと、耳のレベルで使用します。それを取り出します。モジュール間の依存関係が複雑な場合、状況はさらに複雑になります。

アプリケーションのグローバルライブラリを耳のレベルに置くのが最善です。

2
entzik

私のやり方よりも良い方法があるはずですが、私はこれを非常に手動の方法で行う傾向があります。

  1. すべてのJarには、ファイル名にバージョン番号が含まれている必要があります(名前が変更されない場合)。
  2. 各アプリケーションには独自のクラスパスがあります。
  3. 更新されたJar(新しいバージョン)の使用を開始する理由があるはずです。利用可能であるという理由だけで変更するのではなく、必要な機能を提供するという理由で変更してください。
  4. 各リリースには、必要なすべてのJarが含まれている必要があります。
  5. 必要なJarのリスト(これはソースファイルにコード化されています)を認識し、実行時にクラスパス内のJarのリストと照合できるVersionクラスを保持しています。

私が言ったように、それは手動ですが、それは動作します。

0
Ron Tuffin