【发布时间】:2018-03-15 05:06:39
【问题描述】:
我正在尝试在 osgi 环境 (Liferay DXP) 中使用 JAXB 2.2.11。我在创建 JAXBContext 时遇到问题。根据在研究时发现的一些其他来源,如this 和this,我确定在 osgi 容器中我需要为 JAXB 提供正确的类加载器来实例化上下文。所以我有这样的代码:
ClassLoader cl package.with.jaxb.objects.ObjectFactory.class.getClassLoader();
JAXBContext jc = JAXBContext.newInstance("package.with.jaxb.objects ", cl);
此代码导致空指针异常,堆栈跟踪如下:
Caused by: java.lang.NullPointerException
at javax.xml.bind.ContextFinder.handleClassCastException(ContextFinder.java:129)
at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:201)
at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:146)
at javax.xml.bind.ContextFinder.find(ContextFinder.java:371)
at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:446)
at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:409)
查看ContextFinder 的源代码我可以看到context 在第129 行必须为空:
throw handleClassCastException(context.getClass(), JAXBContext.class);
我认为问题可能是我的模块依赖于 jaxb-api 2.2.11,但 jaxb-impl 类由 rt.jar 在运行时提供,并且可能比 2.2.11 更新,因为 Liferay DXP 在 JDK 上运行1.8.为了解决这个问题,我尝试在我的 osgi 模块中包含 jaxb-impl.jar 2.2.11 作为依赖项,然后认为 jaxb-api 和 jaxb-impl 版本会匹配。之后,尝试使用与上面相同的代码创建 JAXBContent 会导致以下错误:
ClassCastException: attempting to cast jar:file:/C:/Program%20Files/Java/jdk1.8.0_144/jre/lib/rt.jar!/javax/xml/bind/JAXBContext.class to bundleresource://623.fwk616113009:13/javax/xml/bind/JAXBContext.class. Please make sure that you are specifying the proper ClassLoader.
从这条消息看来,被实例化的 JAXBContext 来自通过 rt.jar 加载的 JAXBContext 版本。这让我很困惑,因为我希望使用由我的模块的类加载器加载的 JAXBContext 版本,因为我已经在我的模块中包含了 jaxb-impl.jar 并且我已经指定了我的模块的类加载器是用于我对 JAXBContext.newInstance 的调用。谁能阐明我如何让 jaxb 2.2.11 在 osgi 容器中工作?
*请注意,我无法升级模块使用的 jaxb-api 版本,因为 JAXB 代码实际上位于需要 jaxb 2.2.11 的第 3 方 jar 中(我刚刚从现在通过编写一些测试 JAXB 代码来计算公式)。
【问题讨论】:
标签: jaxb osgi osgi-bundle liferay-7