首页 > 解决方案 > Eclipse、Java 11、OSGI 和 JAXB

问题描述

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

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

  1. 一个提供大部分功能的普通 Java 核心库(我们称之为核心)
  2. 一个使用 Core 的纯 Java 命令行工具
  3. 一个 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 模块,而是一个普通的 Eclipse 插件项目,它具有 OSGI 模块作为依赖项)

这允许我在核心上工作,使用测试运行我的 Maven 构建(它会更新 OSGI 项目),然后只需在 Eclipse 中执行 Refresh/Maven 更新以更新插件项目中的所有内容。

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

甚至那部分也有效。几乎。或之类的。实际上,我已经设法通过手动将“javax.xml.bin.annotation”添加到为我的 POM 中的 Felix 插件列出的导出包中来使其“运行”,它会生成一个包含匹配“Export-Package”的 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 插件直接依赖于早期的模块,以及它们的依赖关系?

标签: eclipsemavenjaxbosgijava-11

解决方案


  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.bindEclipse Orbit)获取来自目标平台的依赖项。
  4. 不,见 3。

推荐阅读