それは私にとってかなりうまくいくので、これは誰かを助けるかもしれません.この問題は、独自の依存関係を統合することで解決できます。この簡単な手順に従ってください
まず、次のようなエラーを確認してください:
- メソッドの実行に失敗しました:
- java.lang.LinkageError:ローダーの制約違反:
- メソッド「org.slf4j.impl.StaticLoggerBinder」を解決するとき .getLoggerFactory()Lorg/slf4j/ILoggerFactory;"
- 現在のクラス org/slf4j/LoggerFactory のクラス ローダー (org/openmrs/module/ModuleClassLoader のインスタンス) 、
- および解決されたクラス org/slf4j/impl/StaticLoggerBinder のクラス ローダー (org/apache/catalina/loader/WebappClassLoader のインスタンス) 、
- taticLoggerBinder.getLoggerFactory()Lorg/slf4j/ILoggerFactory 型の異なる Class オブジェクトを持っています。署名で使用
-
ハイライトされた 2 つのクラスを参照してください。 「StaticLoggerBinder.class jar download」および「LoggeraFactory.class jar download」のように Google で検索します。これにより、プロジェクトに含めたjarバージョンの1つである最初または場合によっては2番目のリンク(サイトは http://www.java2s.com )が表示されます。自分でスマートに識別できますが、Google にはまっています;)
-
その後、jar ファイル名がわかります。私の場合は、slf4j-log4j12-1.5.6.jar &slf4j-api-1.5.8 のようになります。
- 現在、このファイルの最新バージョンは http://mvnrepository.com/ から入手できます (実際にはこれまでのすべてのバージョン。これは maven が依存関係を取得するサイトです)。
- ここで、両方のファイルを依存関係として最新バージョンに追加します (または、両方のファイル バージョンを同じままにします。選択したバージョンのいずれかが古い場合)。以下は、pom.xml に含める必要がある依存関係です
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.7</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.7</version>
</dependency>
クラスローダを指定できますか?そうでない場合は、次のようにコンテキスト クラス ローダーを指定してみてください:
Thread thread = Thread.currentThread();
ClassLoader contextClassLoader = thread.getContextClassLoader();
try {
thread.setContextClassLoader(yourClassLoader);
callDom4j();
} finally {
thread.setContextClassLoader(contextClassLoader);
}
私は Java Plugin Framework には詳しくありませんが、Eclipse 用のコードを書いているので、ときどき同様の問題に遭遇します。これで問題が解決するとは限りませんが、試してみる価値はあるでしょう。
クラスローダー階層の問題のように聞こえます。アプリケーションがデプロイされている環境の種類はわかりませんが、Web 環境でこの問題が発生することがあります。この問題は、アプリケーション サーバーが次のようなクラスローダーの階層を作成する場所です:
javahome/lib - ルートとして
appserver/lib - ルートの子として
webapp/WEB-INF/lib - ルートの子の子として
など
通常、クラスローダはロードを親クラスローダに委譲します (これは "parent-first
" として知られています)。 ")、そのクラスローダがクラスを見つけられない場合、子クラスローダはそれを試みます。たとえば、webapp/WEB-INF/lib に JAR としてデプロイされたクラスがクラスをロードしようとすると、最初に対応するクラスローダにappserver/lib を呼び出してクラスをロードし (次に、javahome/lib に対応するクラスローダーにクラスをロードするように要求します)、このルックアップが失敗した場合は、WEB-INF/lib でこのクラスに一致するものが検索されます。
Web 環境では、この階層で問題が発生する可能性があります。たとえば、私が以前に遭遇した間違い/問題の 1 つは、WEB-INF/lib のクラスが appserver/lib にデプロイされたクラスに依存し、そのクラスが WEB-INF/lib にデプロイされたクラスに依存していた場合です。クラスローダは親クラスローダに委譲できますが、ツリーの下に委譲することはできないため、これが失敗の原因でした。そのため、WEB-INF/lib クラスローダーは appserver/lib クラスローダーにクラスを要求し、appserver/lib クラスローダーはそのクラスをロードして依存クラスをロードしようとしますが、appserver/lib または javahome でそのクラスが見つからないため失敗します。 /lib.
そのため、Web/アプリ サーバー環境にアプリをデプロイしていない場合でも、環境にクラスローダーの階層が設定されている場合は、私の説明が長すぎます。そうですか? JPF は、プラグイン機能を実装できるようにするために、ある種のクラスローダー マジックを行っていますか?
LinkageError は、クラス C が複数のクラスローダーによってロードされ、それらのクラスが同じコード (比較、キャストなど) で一緒に使用されているという古典的なケースで得られるものです。同じクラス名であっても、同じ jar からロードされたものであっても問題ありません。あるクラスローダーからのクラスは、別のクラスローダーからロードされた場合、常に別のクラスとして扱われます。
メッセージ (何年にもわたって大幅に改善されています) には次のように書かれています:
Exception in thread "AWT-EventQueue-0" java.lang.LinkageError:
loader constraint violation in interface itable initialization:
when resolving method "org.apache.batik.dom.svg.SVGOMDocument.createAttribute(Ljava/lang/String;)Lorg/w3c/dom/Attr;"
the class loader (instance of org/java/plugin/standard/StandardPluginClassLoader)
of the current class, org/apache/batik/dom/svg/SVGOMDocument,
and the class loader (instance of ) for interface org/w3c/dom/Document
have different Class objects for the type org/w3c/dom/Attr used in the signature
したがって、ここでの問題は、org.w3c.dom.Attr (標準 DOM ライブラリの一部) を使用する SVGOMDocument.createAttribute() メソッドの解決にあります。しかし、Batik でロードされた Attr のバージョンは、メソッドに渡した Attr のインスタンスとは異なるクラスローダーからロードされました。
Batik のバージョンが Java プラグインからロードされているように見えることがわかります。そして、あなたのものは " " からロードされています。これはおそらく組み込みの JVM ローダー (ブート クラスパス、ESOM、またはクラスパス) の 1 つです。
3 つの主要なクラスローダー モデルは次のとおりです。
- 委譲 (JDK のデフォルト - 親に聞いてから私に)
- 委任後 (プラグイン、サーブレット、および分離が必要な場所で一般的 - 私に尋ねてから、親)
- 兄弟 (OSGi、Eclipse などの依存関係モデルで一般的)
JPF クラスローダがどの委任戦略を使用するかはわかりませんが、重要なのは、dom ライブラリの 1 つのバージョンをロードし、全員が同じ場所からそのクラスをソースするようにすることです。これは、クラスパスから削除してプラグインとしてロードするか、Batik がロードしないようにするか、またはその他のことを意味する場合があります。