我正在尝试使用POM-first方法(生成OSGi元数据)将JAXB模块加载为Java 11和Apache Felix的OSGi包。
首先我尝试了:
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-osgi</artifactId>
<version>2.3.3</version>
</dependency>
但是这给了我以下运行时异常:
SCHWERWIEGEND: Implementation of JAXB-API has not been found on module path or classpath.
javax.xml.bind.JAXBException: Implementation of JAXB-API has not been found on module path or classpath.
- with linked exception:
[java.lang.ClassNotFoundException: com.sun.xml.bind.v2.ContextFactory]
这可能与以下问题有关,但我不确定:https://github.com/eclipse-ee4j/jaxb-api/issues/78
所以我尝试了v3.0.0,但现在我的一个注释处理程序使用JAXB生成XML文档,失败了:
Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project my-module: Compilation failure
Implementation of JAXB-API has not been found on module path or classpath.
我注意到jaxb-osgi-3.0.0.jar
不再提供com.sun.xml.bind
包了
我也试图从javax.xml.bind
迁移到jakarta.xml.bind
,但是Maven插件,从xsd生成POJO类,似乎还没有准备好在写作的时候(既不是org.jvnet.jaxb2.maven2:maven-jaxb2-plugin
也不是org.codehaus.mojo:jaxb2-maven-plugin
)。
我的问题:
- 我从哪里可以得到
com.sun.xml.bind
? jaxb-osgi
和jaxb-impl
模块是如何关联的?- 这是怎么回事?
- 我该如何继续?
更新-背景信息
我有以下基于扩展器模式的设置:
- 核心扩展模块M:
- 提供一些JAXB类
- 一个BundleTracker,用于从一些bundle X, Y, Z的META-INF子目录中解编组XML文档
- 一个抽象的自定义注释处理器,用于编组XML文档
- 扩展模块A、B、C:
- 提供额外的JAXB类(从xsd生成)
- 扩展是使用声明式服务 注册的
- 自定义注解
- 注释处理器将注释属性转换为基于JAXB的模型,并在预期位置生成xml文档
- 扩展模块X, Y, Z
- 使用模块A, B, C的注释
- 使用A、B、C的注释处理器生成xml文档
目标:应该很容易创建扩展模块,如X, Y, Z
在Java SE 8中一切正常,其中JAXB仍然与JRE捆绑在一起。
更新1
因为Maven插件还没有准备好,我现在坚持使用v2.3.3。
我修改了以下内容:
我在调用JAXBContext.newInstance时提供了一个类加载器
我在maven-bundle-plugin的几个模块中添加了以下配置:
com.sun.xml.bind。v2, *
这解决了java.lang.ClassNotFoundException: com.sun.xml.bind.v2.ContextFactory
的问题(这似乎不是正确的解决方案,虽然),但现在无法找到ObjectFactory,尽管它们已生成。
更新2
我现在使用修改的jaxb-osgi
包(见问题)和Apache Aries SPI Fly动态编织包(1.3.2)(OSGi ServiceLoader Mediator规范的参考实现),我向核心模块M添加了以下要求:
Require-Capability: [...],osgi.extender;filter:="(o
sgi.extender=osgi.serviceloader.processor)",osgi.serviceloader;filter:=
"(osgi.serviceloader=javax.xml.bind.JAXBContextFactory)";cardinality:=m
ultiple,[...]"
服务似乎被检测到:
2021-02-13 12:09:31 INFO org.apache.aries.spifly.BaseActivator log - Registered provider com.sun.xml.bind.v2.JAXBContextFactory of service javax.xml.bind.JAXBContextFactory in bundle com.sun.xml.bind.jaxb-osgi
2021-02-13 12:09:31 INFO org.apache.aries.spifly.BaseActivator log - Registered provider com.sun.tools.xjc.addon.code_injector.PluginImpl of service com.sun.tools.xjc.Plugin in bundle com.sun.xml.bind.jaxb-osgi
2021-02-13 12:09:31 INFO org.apache.aries.spifly.BaseActivator log - Registered provider com.sun.tools.xjc.addon.locator.SourceLocationAddOn of service com.sun.tools.xjc.Plugin in bundle com.sun.xml.bind.jaxb-osgi
2021-02-13 12:09:31 INFO org.apache.aries.spifly.BaseActivator log - Registered provider com.sun.tools.xjc.addon.sync.SynchronizedMethodAddOn of service com.sun.tools.xjc.Plugin in bundle com.sun.xml.bind.jaxb-osgi
2021-02-13 12:09:31 INFO org.apache.aries.spifly.BaseActivator log - Registered provider com.sun.tools.xjc.addon.at_generated.PluginImpl of service com.sun.tools.xjc.Plugin in bundle com.sun.xml.bind.jaxb-osgi
2021-02-13 12:09:31 INFO org.apache.aries.spifly.BaseActivator log - Registered provider com.sun.tools.xjc.addon.episode.PluginImpl of service com.sun.tools.xjc.Plugin in bundle com.sun.xml.bind.jaxb-osgi
2021-02-13 12:09:31 INFO org.apache.aries.spifly.BaseActivator log - Registered provider com.sun.tools.xjc.addon.accessors.PluginImpl of service com.sun.tools.xjc.Plugin in bundle com.sun.xml.bind.jaxb-osgi
但是我仍然得到:
javax.xml.bind.JAXBException: Implementation of JAXB-API has not been found on module path or classpath.
- with linked exception:
[java.lang.ClassNotFoundException: com.sun.xml.bind.v2.ContextFactory not found by
为什么它试图通过ServiceLoader加载硬编码的默认com.sun.xml.bind.v2.ContextFactory
而不是com.sun.xml.bind.v2.JAXBContextFactory
?
因为每个OSGI包都使用自己的类加载器,所以JAXB API不能使用标准的ServiceLoader
来定位JAXB实现。但是,从2.2.2版本开始,JAXB API可以使用osgi-resource-locator作为回退。
- 添加对
javax.xml.bind
和org.glassfish.hk2.osgiresourcelocator
包的依赖, - 将
osgi-resource-locator
和jaxb-osgi
包与您的包一起部署。
评论:如果你想使用MOXy,你需要额外的步骤,因为MOXy没有随META-INF/services/javax.xml.bind.JAXBContext
文件一起发布(参见这个答案)。