0

クラスパス内の一連の jar で始まる tomcat アプリケーションがあります。

起動後に ClassA、ClassB、ClassC を使用するものとします。したがって、これらのクラスは JVM にロードされます。これらのクラスはすべて、同じフォルダーの異なる jar からロードされます。

ClassB.method()これでClassA から使えるようになりました。それは完全に機能します。

ここで、実行時に別のフォルダーからクラスパスにさらに jar を追加します。これらの jar にも ClassB があります。起動時にロードされた ClassB とこれは異なるバージョンです。

今、ClassB.method()ClassA から使用すると、LinkageError が発生します。

両方の jar が同じバージョンであっても、エラーが発生します。

実行時に新しい jar が JVM に追加されると、ロードされた古いクラスはどうなりますか? ClassA は、最初にロードした ClassB のどのバージョンを保存しますか? 署名の違いがあることを JVM がどのように認識し、エラーをスローするのですか?

実行時に jar を追加するために使用されるコード

URLClassLoader urlClassLoader = (URLClassLoader) ClassLoader.getSystemClassLoader();
Method method = URLClassLoader.class.getDeclaredMethod("addURL", new Class[]{URL.class});   //NO I18N
method.setAccessible(true);

File jarFolder = new File("<path-to-new-jar-folder>");
Collection<File> jarFiles = FileUtils.listFiles(jarFolder, new String[]{ "jar"}, true);         //NO I18N

for(File jarFile : jarFiles)
{
    method.invoke(urlClassLoader, jarFile.toURI().toURL());
}

リンケージエラー

java.lang.LinkageError: ローダー制約違反: メソッド "org.apache.http.client.methods.HttpPost.setEntity(Lorg/apache/http/HttpEntity;)V" を解決するとき、クラス ローダー (java/net/URLClassLoader のインスタンス)現在のクラスの com/application/rest/tokens/TokenHandler と、メソッドを定義するクラス org/apache/http/client/methods/HttpEntityEnclosingRequestBase のクラス ローダー (sun/misc/Launcher$AppClassLoader のインスタンス) を持っています。署名で使用されるタイプ org/apache/http/HttpEntity の異なる Class オブジェクト

4

0 に答える 0