【问题标题】:Eclipse, Java 11, OSGI, and JAXBEclipse、Java 11、OSGI 和 JAXB
【发布时间】:2021-03-02 08:22:45
【问题描述】:

试图让 Eclipse、Java 11、OSGI 和 JAXB 合作让我头疼不已。

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

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

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

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

这在 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 注释的模型添加扩展类。不仅如此,他们将(我假设)必须使用与核心库相同的 JAXB API 库(通过 OSGI 包装器包含在插件中)。假设:我必须在 OSGI 包装器中导出 JAXB API 包,以便客户端项目(即插件)可以使用它们,而不必带来它们自己的(可能是冲突的)JAXB 依赖项。

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

但是 Eclipse 抱怨 OSGI 清单:

此插件中不存在包'javax.xml.bind.annotation'

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

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

  1. 如果在实际的 Eclipse 插件中确实工作,为什么 Eclipse 会抱怨 OSGI 清单?有什么方法可以修复清单吗?
  2. 让 OSGI/Eclipse 方面从普通的 Java Core 获取 JAXB 依赖项是正确的方法吗?
  3. 如果没有,我怎样才能通过 OSGI 方式将 JAXB 依赖项放入插件中? (我还没有找到任何关于如何以及在哪里获得正确的信息,标准实现的最新 OSGI 依赖项(API 的 java.xml.bind 和实现的 com.sun.xml.bind,如果我已经做对了)或 Moxy)我如何确保处理 JAXB 上下文并且对 OSGI & Co 一无所知的纯 Java 核心代码能够理解 OSGI 端的注释,如果这带来了自己独立的 JAXB 依赖关系?李>
  4. (额外问题)我的 OSGI 包装器项目真的有必要吗?有没有办法让 Maven 设置构建一些简单的 Java 模块,并作为最后一项直接依赖于早期模块及其依赖项的 Eclipse 插件?

【问题讨论】:

  • Maven 在构建时解决依赖关系。在 Eclipse/OSGi 中插件/包可以在运行时停止和启动,因此依赖关系也必须在运行时解决。当您想在普通 Java 应用程序以及像 Eclipse 这样的 OSGi 应用程序中使用相同的 JAR 时,您必须在 pom.xmlMETA-INF/MANIFEST.MF 中指定两次依赖项。可以肯定的是,两个依赖项定义都是正确的,您还必须构建 JAR 两次,例如使用普通的 Maven 和 Maven+Tycho。普通 Maven(没有 Tycho)无法解析 OSGi Import-Package 依赖项。

标签: eclipse maven jaxb osgi java-11


【解决方案1】:
  1. Java 11 的系统库不再包含javax.xml.bind.annotation。这意味着现在缺少的包必须由插件/捆绑包包含和导出。使用 javax.xml.bind.annotation 的插件/包现在必须有对应的 Import-Package(推荐)或 Require-Bundle(不推荐)条目。
  2. 不,因为它需要是一个 OSGi 包。 Maven 本身无法解析 OSGi 依赖项,因为例如 Import-Package 语句基于包级别的版本控制,但在 Maven 存储库中只有模块/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。

【讨论】:

  • 谢谢,这有帮助——但(还)没有我想象的那么好:我仍然不知道如何让它工作。我创建了一个只有两个模块的测试项目。模块 A 完成 JAXB 的工作,而 B 是调用它的 Eclipse 插件。但是我必须在 A 中依赖什么才能让 JAXB 正常工作?我目前依赖于 Jakarta 绑定 API 和 Sun JAXB impl。它编译并且所有的类都在那里,但是 API 想要使用错误的 ContextFactory(com.sun.xml.internal.bind.v2.ContextFactory),而存在于 impl 中的那个(同样没有“内部”)“是不是 API”,无法加载。
  • 原来我一直在与两个不同的问题作斗争。我已经解决了依赖问题(经过多次试验和错误)并且遇到了类加载器问题。我已经接受了您的回答并为新问题创建了一个后续线程:stackoverflow.com/questions/64979229/… 在我清理完所有内容后,我将尝试发布一个工作示例项目以供将来参考。
猜你喜欢
  • 2019-03-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-24
  • 1970-01-01
  • 2014-12-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多