首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何处理Java中的链接错误?

如何处理Java中的链接错误?
EN

Stack Overflow用户
提问于 2018-03-29 06:52:28
回答 2查看 0关注 0票数 0

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

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

在控制台上,我知道发生了一个错误:

代码语言:javascript
复制
线程“AWT-EventQueue-0”中的异常java.lang.LinkageError:接口中的加载器约束违规itable初始化:何时解析方法“org.apache.batik.dom.svg.SVGOMDocument.createAttribute(Ljava / lang / String;)Lorg / W3C / DOM /的Attr;” 当前类的类加载器(org / java / plugin / standard / StandardPluginClassLoader的实例)org / apache / batik / dom / svg / SVGOMDocument,以及接口org / w3c的类加载器(<bootloader>的实例)对于签名中使用的org / w3c / dom / Attr类型,dom / Document具有不同的Class对象
    在org.apache.batik.dom.svg.SVGDOMImplementation.createDocument(SVGDOMImplementation.java:149)
    在org.dom4j.io.DOMWriter.createDomDocument(DOMWriter.java:361)
    在org.dom4j.io.DOMWriter.write(DOMWriter.java:138)

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

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

您有没有遇到过这样的问题,并且有任何想法如何解决这个问题,或者至少能够解决问题的核心问题?

EN

回答 2

Stack Overflow用户

发布于 2018-03-29 15:27:59

LinkageError是你在一个经典的案例中得到的,你有一个类C被多个类加载器加载,并且这些类在相同的代码中被使用(比较,转换等)。无论它是否是相同的Class名称,或者即使它是从相同的jar中加载也没关系 - 如果从另一个类加载器加载,则来自一个classloader的Class始终被视为不同的Class。

这个消息(这些年来有所改善)说:

代码语言:javascript
复制
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或类路径)。

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

  • 代表团(在JDK中默认 - 请问父母​​,然后我)
  • 后授权(常见于插件,servlet和要隔离的地方 - 问我,然后是父母)
  • (在OSGi,Eclipse等依赖模型中很常见)

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

票数 0
EN

Stack Overflow用户

发布于 2018-03-29 16:26:15

听起来像一个类加载器层次结构问题。我无法确定应用程序的部署环境是什么类型,但有时候这种问题可能发生在Web环境中 - 应用程序服务器在其中创建类加载程序的层次结构,类似于以下内容:

javahome / lib - 作为根 appserver / lib - 作为根 webapp / WEB-INF / lib的子节点 - 作为根子节点的子节点 等

通常,类加载器将加载委托给它们的父类加载器(这称为“ parent-first”),如果该类加载器找不到该类,则子类加载器将尝试执行。例如,如果在webapp / WEB-INF / lib中部署为JAR的类尝试加载类,则首先会要求与appserver / lib对应的类加载器加载该类(然后请求与javahome / lib相对应的类加载器加载类),如果查找失败,则搜索WEB-INF / lib以匹配此类。

在Web环境中,您可能遇到此层次结构的问题。例如,之前遇到的一个错误/问题是,WEB-INF / lib中的类取决于部署在appserver / lib中的类,而该类又取决于部署在WEB-INF / lib中的类。这导致失败,因为虽然类加载器能够委派给父类加载器,但他们不能将其委托回树中。因此,WEB-INF / lib类加载器会向appserver / lib类加载器请求一个类,appserver / lib类加载器将加载该类并尝试加载相关类,并失败,因为它无法在appserver / lib或javahome中找到该类/ lib目录下。

因此,虽然您可能未在Web /应用程序服务器环境中部署您的应用程序,但如果您的环境设置了类加载程序的层次结构,则我的太长解释可能适用于您。可以?JPF是否能够实现某种类型的加载器魔法来实现它的插件功能?

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/-100007861

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档