gpt4 book ai didi

java - 如何处理 Java 中的 LinkageErrors?

转载 作者:IT老高 更新时间:2023-10-28 12:32:29 25 4
gpt4 key购买 nike

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

我的应用程序,使用 Java Plugin Framework ,似乎无法转换 dom4j -创建 XML 文档到 Batik's SVG 规范的实现。

在控制台上,我得知发生了错误:

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的原始类加载器和插件框架部署的类加载器之间的冲突引起的。

据我所知,无法为要使用的框架指定类加载器。破解它可能是可能的,但我更喜欢用不那么激进的方法来解决这个问题,因为(无论出于何种原因)它只发生在 Linux 系统上。

你们中有人遇到过这样的问题吗?知道如何解决它或至少找到问题的核心吗?

最佳答案

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

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

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

三个突出的类加载器模型是:

  • 委托(delegate)(JDK 中的默认设置 - 先问 parent ,然后再问我)
  • 委派后(常见于插件、servlet 和您想要隔离的地方 - 询问我,然后询问 parent )
  • 兄弟(在 OSGi、Eclipse 等依赖模型中很常见)

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

关于java - 如何处理 Java 中的 LinkageErrors?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/244482/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com