クラスローダーの問題-どのライブラリーバージョン(jarファイル)がロードされているかを判別する方法
-
02-07-2019 - |
質問
別の問題を解決しました*私は、このバージョンのライブラリを使用していますが、見かけ上は、私のアプリサーバーは既にロードされていますこのライブラリのバージョン*問題(ため息)。
アプリケーションが適切なすべてのjarファイルにアクセスできるか、ロードされたクラスバージョンにアクセスできるかどうかを確認(または監視)するための良い方法を誰か知っていますか?
事前に感謝します!
[P.S。私の見解で OSGiモジュールアーキテクチャを使い始める非常に良い理由です!]
更新:この記事も役立ちました!ログファイルに書き込むことで、どのクラスのJBossのクラスローダーがロードされたのかがわかりました。
解決
JBossを使用している場合、MBean(クラスローダーリポジトリiirc)があり、特定のクラスをロードしたすべてのクラスローダーを要求できます。
他のすべてが失敗した場合は、常に 'java -verbose:class'があり、ロードされるすべてのクラスファイルのjarの場所が出力されます。
他のヒント
jarマニフェストに適切なバージョン情報がある場合、バージョンを取得してテストする方法があります。マニフェストを手動で読む必要はありません。
java.lang.Package .getImplementationVersion()およびgetSpecificationVersion()およびisCompatibleWith()は、探していることを実行するように聞こえます。
他の方法の中でも、this.getClass()。getPackage()を使用してパッケージを取得できます。
java.lang.Packageのjavadocは、これらの属性に特定のマニフェスト属性名を与えていません。簡単なGoogle検索で 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からクラスをロードすることを覚えておく必要があります。たとえば、warファイルにlog4j v1、earレベルにlog4j v2をパッケージ化し、app-serverのクラスパスにlog4j v3を配置すると、モジュールは独自のモジュールのjarを使用します。それを取り除いて、耳のレベルのものを使用します。それを取り出して、アプリサーバーのクラスパスにあるものを使用します。モジュール間に複雑な依存関係がある場合、事態はさらに複雑になります。
最良の方法は、アプリケーションのグローバルライブラリをイヤーレベルに配置することです。
私がやるよりも良い方法があるはずですが、私はこれを非常に手作業で行う傾向があります。
- すべてのJarのファイル名にはバージョン番号が必要です(名前を変更しない場合)。
- 各アプリケーションには独自のクラスパスがあります。
- 更新されたJar(新しいバージョン)の使用を開始する理由が必要です。利用できるからといって変更するのではなく、必要な機能を提供するから変更してください。
- 各リリースには、必要なすべてのジャーが含まれている必要があります。
- 必要なJarのリストを知っているVersionクラスを保持し(これはソースファイルにコード化されています)、実行時にクラスパス内のJarのリストと照合できます。
私が言ったように、それは手動ですが、動作します。