0

我有一个从类路径中的一组 jar 开始的 tomcat 应用程序。

假设启动后使用ClassA、ClassB、ClassC。因此,这些类被加载到 JVM 中。所有这些类都是从同一文件夹中的不同 jar 加载的。

现在,我可以ClassB.method()从 ClassA 使用。它完美地工作。

现在,我在运行时将来自不同文件夹的更多 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/HttpEntityEnclosureRequestBase 的类加载器(sun/misc/Launcher$AppClassLoader 的实例)签名中使用的 org/apache/http/HttpEntity 类型的不同 Class 对象

4

0 回答 0