Hibernate和Apache Felix的依赖链冲突

我理解OSGi抱怨多个依赖链的概念 – 一个包可以多次使用,当导入包没有准确指定它需要的版本时,OSGi容器可能会遇到不知道提供什么的麻烦。

不幸的是,本周我遇到了这样一个问题,但两个捆绑都是第三方捆绑,所以我无法真正影响他们的import和出口。 以下是我收到的两条错误消息:

org.osgi.framework.BundleException: Uses constraint violation. Unable to resolve bundle revision org.hibernate.core [28.0] because it is exposed to package 'javax.xml.stream' from bundle revisions com.springsource.javax.xml.stream [23.0] and org.apache.felix.framework [0] via two dependency chains. Chain 1: org.hibernate.core [28.0] import: (osgi.wiring.package=javax.xml.stream) | export: osgi.wiring.package=javax.xml.stream com.springsource.javax.xml.stream [23.0] Chain 2: org.hibernate.core [28.0] import: (osgi.wiring.package=javax.xml.transform.stax) | export: osgi.wiring.package=javax.xml.transform.stax; uses:=javax.xml.stream export: osgi.wiring.package=javax.xml.stream org.apache.felix.framework [0] at org.apache.felix.framework.Felix.resolveBundleRevision(Felix.java:3824) at org.apache.felix.framework.Felix.startBundle(Felix.java:1868) at org.apache.felix.framework.Felix.setActiveStartLevel(Felix.java:1191) at org.apache.felix.framework.FrameworkStartLevelImpl.run(FrameworkStartLevelImpl.java:295) at java.lang.Thread.run(Thread.java:724) org.osgi.framework.BundleException: Uses constraint violation. Unable to resolve bundle revision org.hibernate.core [28.0] because it is exposed to package 'javax.xml.stream' from bundle revisions org.apache.felix.framework [0] and com.springsource.javax.xml.stream [23.0] via two dependency chains. Chain 1: org.hibernate.core [28.0] import: (osgi.wiring.package=javax.xml.stream) | export: osgi.wiring.package=javax.xml.stream org.apache.felix.framework [0] Chain 2: org.hibernate.core [28.0] import: (osgi.wiring.package=org.dom4j.io) | export: osgi.wiring.package=org.dom4j.io; uses:=javax.xml.stream com.springsource.org.dom4j [27.0] import: (&(osgi.wiring.package=javax.xml.stream)(version>=1.0.1)(!(version>=2.0.0))) | export: osgi.wiring.package=javax.xml.stream com.springsource.javax.xml.stream [23.0] at org.apache.felix.framework.Felix.resolveBundleRevision(Felix.java:3824) at org.apache.felix.framework.Felix.startBundle(Felix.java:1868) at org.apache.felix.framework.Felix.setActiveStartLevel(Felix.java:1191) at org.apache.felix.framework.FrameworkStartLevelImpl.run(FrameworkStartLevelImpl.java:295) at java.lang.Thread.run(Thread.java:724) 

当我尝试从已安装的软件包中删除com.springsource.javax.xml.streamcom.springsource.org.dom4j抱怨缺少软件包javax.xml.stream

我检查了org.apache.felix.frameworkMANIFEST.MF文件,因为我真的很惊讶Felix显然导出了javax.xml.stream ,但它不包含这样的条目。 此外, dom4j包不会根据它的清单重新导出流包。

我真的很感激任何可以让我更接近回答这个依赖链问题来自哪里的提示。 从我的角度来看,除了com.springsource.javax.xml.stream导出所述包之外,我找不到一个包 –

如果包在bundle中以及bpot类路径(JDK)中可用,则通常会出现问题。 如果该包从另一个JDK包连接并且也直接从包中连接,那么这甚至是一个更大的问题。 在您的情况下,问题如下:

  • javax.xml.transform.stax仅在引导类路径(JDK)上可用,因此hibernate.core连接到该包。
  • 由于javax.xml.transform.stax来自引导类路径,因此它可以连接到引导类路径上的另一个包。 它需要javax.xml.stream,因此它将连接到来自JDK的包

我们有链:

 hibernate.core -> javax.xml.transform.stax -> javax.xml.stream 

另一方面,hibernate.core直接连接到javax.xml.stream。 可能它甚至在Import-Package部分使用了一个版本,因此它无法连接到来自JDK的包。

我们有链:

 hibernate.core -> javax.xml.stream 

这会产生冲突。 由于hibernate.core在javax.xml.transform.stax的帮助下使用javax.xml.stream API,因此hibernate.corejavax.xml.transform.stax应该使用相同的javax.xml.stream类。 但是,他们没有。

您有几个选项可以解决您的问题:

您可以安装包含javax.xml.transform.stax包的包。 该包将能够连接到来自bundle的javax.xml.stream包,并且hibernate.core可以连接到包含javax.xml.transform.stax的包。 你可以祈祷接线总是好的。

根据我的经验,框架启动后电线很好。 由于软件包版本在软件包中较高,因此从其他软件包导入软件包时,它们将是首选。 但是,当捆绑包在运行时更新和刷新时,布线通常会出错。 我不知道为什么,它只是发生了。

为了避免每个问题,我通常会从引导类路径中排除那些也在bundle中可用的包。

您的下一个问题可能是这些API经常使用工厂类。 当有人使用这样的工厂时,工厂类的类加载器也必须看到实现类。 我创建了一个包含所有xmlcommons包的包。 它包含所有xml-apis类和它们的实现(xerces,xalan等)。 它可能对你有所帮助。 如果此捆绑包解决了您的问题,请告诉我。 在这种情况下,我将花时间最终收集所有必要的数据(许可到pom,来源)并将其发布到maven-central,这样它也可以帮助其他人。