如何处理Java中的LinkageErrors? [英] How to deal with LinkageErrors in Java?

查看:143
本文介绍了如何处理Java中的LinkageErrors?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

开发一个基于XML的大量Java应用程序,我最近在Ubuntu Linux上遇到了一个有趣的问题。

Developing a heavily XML-based Java-application, I recently encountered an interesting problem on Ubuntu Linux.

我的应用程序,使用 Java插件框架,似乎无法转换 dom4j 创建了XML文档,以 Batik 实现SVG规范。

My application, using the Java Plugin Framework, appears unable to convert a dom4j-created XML document to Batik's implementation of the SVG specification.

在控制台上,我了解到发生了错误:

On the console, I learn that an error occurs:


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 <bootloader>) for interface org/w3c/dom/Document have different Class objects for the type org/w3c/dom/Attr used in the signature
    at org.apache.batik.dom.svg.SVGDOMImplementation.createDocument(SVGDOMImplementation.java:149)
    at org.dom4j.io.DOMWriter.createDomDocument(DOMWriter.java:361)
    at org.dom4j.io.DOMWriter.write(DOMWriter.java:138)

我认为这个问题是由JVM的原始类加载器和插件框架部署的类加载器之间的冲突引起的。

I figure that the problem is caused by a conflict between the original classloader from the JVM and the classloader deployed by the plugin framework.

据我所知,不可能为框架指定一个类加载器。有可能破解它,但我更倾向于采用不那么积极的方法来解决这个问题,因为(无论出于什么原因)它只发生在Linux系统上。

To my knowledge, it's not possible to specify a classloader for the framework to use. It might be possible to hack it, but I would prefer a less aggressive approach to solving this problem, since (for whatever reason) it only occurs on Linux systems.

已经你们中的一个遇到过这样的问题,并且知道如何修复它或至少解决问题的核心?

Has one of you encountered such a problem and has any idea how to fix it or at least get to the core of the issue?

推荐答案

LinkageError是您在经典案例中获得的,其中您有一个由多个类加载器加载的类C,并且这些类在同一代码中一起使用(比较,强制转换等)。如果它是相同的类名称或者它是从相同的jar加载也没关系 - 如果从另一个类加载器加载,则来自一个类加载器的类总是被视为不同的类。

LinkageError is what you'll get in a classic case where you have a class C loaded by more than one classloader and those classes are being used together in the same code (compared, cast, etc). It doesn't matter if it is the same Class name or even if it's loaded from the identical jar - a Class from one classloader is always treated as a different Class if loaded from another classloader.

这条消息(多年来已经有了很大的改进)说:

The message (which has improved a lot over the years) says:

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

所以,这里的问题在于解析SVGOMDocument.createAttribute()方法,该方法使用org.w3c.dom.Attr(标准DOM库的一部分)。但是,加载了Batik的Attr版本是从一个不同的类加载器加载的,而不是你传递给该方法的Attr实例。

So, here the problem is in resolving the SVGOMDocument.createAttribute() method, which uses org.w3c.dom.Attr (part of the standard DOM library). But, the version of Attr loaded with Batik was loaded from a different classloader than the instance of Attr you're passing to the method.

你会看到Batik的版本似乎是从Java插件加载的。你的是从加载的,它很可能是内置的JVM加载器之一(引导类路径,ESOM或类路径)。

You'll see that Batik's version seems to be loaded from the Java plugin. And yours is being loaded from " ", which is most likely one of the built-in JVM loaders (boot classpath, ESOM, or classpath).

三个着名的类加载器模型是:

The three prominent classloader models are:


  • 委托(默认情况下) JDK - 询问父母,然后是我)

  • 授权后(常见于插件,servlet和你想要隔离的地方 - 问我,然后是父母)

  • 兄弟(在OSGi,Eclipse等依赖模型中很常见)

我不知道JPF类加载器的委托策略是什么使用,但关键是您希望加载一个版本的dom库,并且每个人都从同一位置获取该类。这可能意味着将其从类路径中删除并作为插件加载,或阻止Batik加载它或其他东西。

I don't know what delegation strategy the JPF classloader uses, but the key is that you want one version of the dom library to be loaded and everyone to source that class from the same location. That may mean removing it from the classpath and loading as a plugin, or preventing Batik from loading it, or something else.

这篇关于如何处理Java中的LinkageErrors?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆