解决 OSGi 环境中“org.w3c.dom.Node”上的“加载程序约束违规”错误

Posted

技术标签:

【中文标题】解决 OSGi 环境中“org.w3c.dom.Node”上的“加载程序约束违规”错误【英文标题】:Solving a "loader constraint violation" error on "org.w3c.dom.Node" in an OSGi environment 【发布时间】:2013-07-26 17:47:28 【问题描述】:

我的 OSGi 环境中出现以下错误:

java.lang.LinkageError: loader constraint violation: loader (instance of <bootloader>) previously initiated loading for a different type with name "org/w3c/dom/Node"
    at javax.imageio.metadata.IIOMetadata.getStandardTree(IIOMetadata.java:716)
    at com.sun.imageio.plugins.gif.GIFImageMetadata.getAsTree(GIFImageMetadata.java:128)
    at com.xmlmind.fo.graphic.GraphicFactoryImpl.getResolution(GraphicFactoryImpl.java:184)
    at com.xmlmind.fo.graphic.GraphicFactoryImpl.createGraphic(GraphicFactoryImpl.java:145)
    at com.xmlmind.fo.graphic.GraphicFactories.createGraphic(GraphicFactories.java:128)
    at com.xmlmind.fo.converter.Converter.createGraphic(Converter.java:1943)
    at com.xmlmind.fo.converter.Converter.startExternalGraphic(Converter.java:1910)
    at com.xmlmind.fo.converter.Converter.startElement(Converter.java:635)
    at org.apache.xerces.parsers.AbstractSAXParser.startElement(Unknown Source)
    at org.apache.xerces.parsers.AbstractXMLDocumentParser.emptyElement(Unknown Source)
    at org.apache.xerces.impl.XMLNSDocumentScannerImpl.scanStartElement(Unknown Source)
    at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl$FragmentContentDispatcher.dispatch(Unknown Source)
    at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
    at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
    at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
    at org.apache.xerces.parsers.XMLParser.parse(Unknown Source)
    at org.apache.xerces.parsers.AbstractSAXParser.parse(Unknown Source)
    at org.apache.xerces.jaxp.SAXParserImpl$JAXPSAXParser.parse(Unknown Source)
    at org.apache.xerces.jaxp.SAXParserImpl.parse(Unknown Source)
    at com.xmlmind.fo.converter.Converter.convert(Converter.java:417)

问题在于此调用来自导入 org.w3c.dom.Node 的包

(来自“xml-apis”包),因为这是javax.imageio.metadata.IIOMetadatagetAsTree(String formatName)方法的返回类型,而这个类本身从系统包中导入org.w3c.dom.Node,因为它驻留在系统中捆。

这会导致org.w3c.dom.Node 被两个不同的类加载器加载,因此在调用getAsTree 方法时会导致上面显示的加载器约束冲突。

“xml-apis”包在此 OSGi 环境中是必需的,因为它提供了与系统包不同版本的 org.w3c.dom 包(例如,org.w3c.dom.ElementTraversal 类可以在“xml-apis”中找到捆绑包(并且被我环境中的其他捆绑包使用),但在系统捆绑包中不存在)。

javax.imageio 包在单独的包中不可用,因此我不能“强制”它使用“xml-apis”导入。 我还尝试在调用 bundle 中显式导入 org.w3c.dom 的版本“0.0.0”(系统包“版本”),但这也不起作用,因为这会导致其他导入上的“包使用冲突”(其中有org.w3c.dom 作为使用约束)。

我现在有点想不通。有谁知道我该如何解决这个问题?非常感谢您提前提供的帮助!

【问题讨论】:

我遇到了类似的问题,因此我将许多与 xml 相关的类移到了一个包中,该包可在 repository.everit.biz/nexus/content/groups/public/org/everit/… 获得。之后,我从 osgi 引导类路径中删除了这个包中已经存在的 javax.xml 包。因为一切似乎都运行良好。 谢谢你的建议,我会试试的! @Balazs:不幸的是,使用该捆绑包并没有解决错误,因为仍然有两个不同的类加载器试图加载 org.w3c.dom.Node。彼得在下面的回答解决了这个问题。不过感谢您的建议! 【参考方案1】:

一种可能性(实际上在 bnd(tools) 中很容易)是将 XML API 包放在正常的类路径中。假设新的 javax.xml.* 向后兼容,您将获得这些 API 的至少一个定义。在 bndtools 你会添加:

-runpath: $repo;xml-apis__xml-apis # assuming the bsn = xml-apis__xml-apis

您还必须添加额外的系统包。

当然,真正的问题是 Java 不对它的包进行版本控制,给你留下了这个烂摊子……

【讨论】:

谢谢,效果很好!这个案例确实非常清楚地表明我们需要对 JRE 中的包进行版本控制。这样的解决方法感觉很尴尬,希望版本控制很快就会到来!

以上是关于解决 OSGi 环境中“org.w3c.dom.Node”上的“加载程序约束违规”错误的主要内容,如果未能解决你的问题,请参考以下文章

关于运行osgi插件时和运行环境相关的问题

OSGI 环境中的依赖注入

基于OSGi的Virgo环境搭建——环境篇

osgi+camel+karaf运行环境搭建

如何配置OSGi环境以便可以从EclipseStarter类中使用它?

在 OSGi 环境中,类路径和类加载器是如何设置的?