Eclipse、Java11、OSGI 和 JAXB

Eclipse, Java 11, OSGI, and JAXB

让 Eclipse、Java11、OSGI 和 JAXB 合作让我很头疼。

我的项目由几个模块组成:

  1. 一个普通的 Java 核心库(我们称之为核心),提供大部分功能
  2. 使用 Core
  3. 的普通 Java 命令行工具
  4. 一个 Eclipse 插件(在 IDE 中使用)(我们称之为插件),它也使用核心

核心有几个可以扩展功能的地方。在普通 Java 方面,这是通过服务加载器自动完成的,但也有手动注册扩展的挂钩。插件定义扩展点并使用它们的数据调用这些注册挂钩。

问题来了:Core 具有通过 JAXB 在我的 Java 模型和 XML 之间序列化和反序列化模型树的代码。模型的某些部分来自扩展 - 在创建 JAXB 上下文时,我列出了我的模型根 class 和所有扩展 classes 作为我的上下文 classes.

这在 Java 端工作正常,但在 Eclipse 端会导致问题,我将在下面描述。

我正在使用 Maven 构建整个项目。不是因为我喜欢 Maven(我不喜欢),而是因为 Eclipse 的构建文档非常薄,而且我至少大致了解了使用 Maven 构建插件的方法。我一直无法弄清楚如何创建直接包含我的普通 Java 核心的 Eclipse 插件项目(无需手动将每个更新的核心构建复制到插件中),但经过多次摆弄使用 Apache Felix Maven 插件,我设法获得了以下可用的模块系统:

  1. 核心模块(打包类型:jar)
  2. 命令行模块(打包类型:jar,创建可执行jar;与本次讨论无关)
  3. OSGI模块(打包类型:bundle)
  4. Eclipse 插件(不是 Maven 模块,而是将 OSGI 模块作为依赖项的普通 Eclipse 插件项目)

这让我可以在核心上工作,运行 我的 Maven 构建测试(更新 OSGI 项目)然后简单地在 Eclipse 中做一个 Refresh/Maven 更新来更新插件项目。

现在一切正常,包括 JAXB 序列化,只要我自己不必在插件中访问 JAXB(即只需在 Core 中调用我的 API 方法)。由于扩展机制,插件现在将向需要 JAXB 注释的模型添加扩展 classes。不仅如此,他们(我假设)必须使用与核心库相同的 JAXB API 库(通过 OSGI 包装器包含在插件中)。假设:我必须在 OSGI 包装器中导出 JAXB API 包,以便客户端项目(即插件)可以使用它们,而不必带来它们自己的(可能是冲突的)JAXB 依赖项。

甚至那部分也有效。几乎。或者有点。实际上,我已经通过手动将“javax.xml.bin.annotation”添加到我的 POM 中为 Felix 插件列出的导出包中来“运行ning”,并且它生成了一个 OSGI 清单,其中包含一个匹配的“导出包”条目。插件现在使用 JAXB 注释进行编译,并且核心可以正确处理插件的 JAXB 注释 classes。

但是 Eclipse 抱怨 OSGI 清单:

Package 'javax.xml.bind.annotation' does not exist in this plug-in

这不仅意味着我每次启动插件时都必须单击警告对话框(因为 Eclipse 认为它的依赖项之一已损坏),而且 a) 我预计一次部署会出现重大问题我已经完成了开发,并且 b) 我有一种奇怪的感觉,我正在以错误的方式去做这件事。

经过这么长的(但我想是必要的)描述归结为这些问题:

  1. 如果 Eclipse 在实际的 Eclipse 插件中确实 有效 ,为什么 Eclipse 会抱怨 OSGI 清单?有什么方法可以修复清单吗?
  2. 让 OSGI/Eclipse 端从普通 Java Core 获取 JAXB 依赖项是正确的方法吗?
  3. 如果没有,我如何才能以 OSGI 方式将 JAXB 依赖项添加到插件中? (我还没有找到任何关于如何以及在何处获得正确的信息,无论是标准实现的最新 OSGI 依赖关系(java.xml.bind 用于 API 和 com.sun.xml.bind 用于实现,如果我我做对了)或 Moxy)我如何确保我的普通 Java 核心代码(处理 JAXB 上下文并且对 OSGI & Co 一无所知)理解 OSGI 端的注释(如果它有自己的注释)单独的 JAXB 依赖项?
  4. (奖金问题)我的 OSGI 包装器项目真的有必要吗?有没有办法建立一个 Maven 设置来构建一些简单的 Java 模块,并且作为它的最后一项直接依赖于早期模块及其依赖项的 Eclipse 插件?
  1. Java11 的系统库不再包含javax.xml.bind.annotation。这意味着现在丢失的包必须由 plugin/bundle 包含和导出。 Plugins/bundles 使用 javax.xml.bind.annotation 现在必须有相应的 Import-Package(推荐)或 Require-Bundle(不推荐)条目。
  2. 不,因为它需要是一个 OSGi 包。 Maven 本身无法解决 OSGi 依赖关系,因为例如 Import-Package 语句基于包级别版本控制,但在 Maven 存储库中只有 module/JAR 级别的版本。
  3. 当您想在普通 Java 应用程序和像 Eclipse 这样的 OSGi 应用程序中使用相同的 JAR 时,您必须在 pom.xmlMETA-INF/MANIFEST.MF。可以肯定的是,这两个依赖项定义都是正确的,您还必须构建 JAR 两次,例如使用普通 Maven 和使用 Maven+Tycho。普通 Java 应用程序的构建将从例如Maven 存储库和 Eclipse 插件的构建将从 p2 存储库的目标平台获取依赖项(在您的情况下,例如 javax.xml.bind 来自 Eclipse Orbit)。
  4. 没有。参见 3.