java - JAXB + OSGi 与 Java 11

标签 java jaxb osgi java-11 apache-felix

我尝试使用 POM 优先方法将 JAXB 模块作为 OSGi bundle 与 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 ,但是从 XSD 生成 POJO 类的 Maven 插件在撰写本文时似乎尚未准备好( org.jvnet.jaxb2.maven2:maven-jaxb2-pluginorg.codehaus.mojo:jaxb2-maven-plugin 都没有)。

我的问题:

  1. 在哪里可以获得 com.sun.xml.bind来自?
  2. 怎么办 jaxb-osgijaxb-impl模块相关吗?
  3. 这一切应该如何运作?
  4. 我该如何继续?

更新 - 背景信息

我有以下基于 Extender Pattern 的设置:

  • 核心扩展模块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包(参见 issue )和 Apache Aries SPI Fly Dynamic Weaving Bundle (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 

为什么它尝试加载硬编码的默认值 com.sun.xml.bind.v2.ContextFactory而不是com.sun.xml.bind.v2.JAXBContextFactory通过ServiceLoader?

最佳答案

由于每个 OSGI 包都使用自己的类加载器,因此 JAXB API 无法使用标准 ServiceLoader 来定位 JAXB 实现。但是,从版本 2.2.2 开始,JAXB API 可以使用 osgi-resource-locator作为后备。

因此,为了在 Java 11 上使用 JAXB,您只需:

  1. 添加对 javax.xml.bindorg.glassfish.hk2.osgiresourcelocator 软件包的依赖项,
  2. 部署 osgi-resource-locatorjaxb-osgi与您的 bundle 一起捆绑。

备注:如果您想使用 MOXy,则需要额外的步骤,因为 MOXy 不附带 META-INF/services/javax.xml.bind.JAXBContext 文件(参见 this answer )。

关于java - JAXB + OSGi 与 Java 11,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65868619/

相关文章:

java - OSGi Bundle 无法自动解析

java - 是否有 Eclipse 有用的 Add On for AutoComplete function like xCode?

java - 布局管理器的使用

java - xml 文件的解码

java - Jersey - 从 XML 字符串填充 java beans

java - 从 FrameworkUtil 类获取 BundleContext 后抛出 NPE

java - 使用kura框架,连接BLE设备时如何指定地址类型为 "random static"

java - 无法在下一个屏幕上看到汉堡菜单

java - SimGrid:如何检查主机是否正在执行任务?

xml - JaxB 在从 XSD 生成枚举时添加 undescore(_)