eclipse - Eclipse、Java 11、OSGI 和 JAXB
问题描述
试图让 Eclipse、Java 11、OSGI 和 JAXB 合作让我头疼不已。
我的项目由几个模块组成:
- 一个提供大部分功能的普通 Java 核心库(我们称之为核心)
- 一个使用 Core 的纯 Java 命令行工具
- 一个 Eclipse 插件(用于 IDE)(我们称之为插件),它也使用核心
核心有几个点可以扩展功能。在纯 Java 方面,这是通过服务加载程序自动完成的,但也有手动注册扩展的钩子。插件定义扩展点并使用它们的数据调用这些注册钩子。
问题来了:Core 有代码可以通过 JAXB 在我的 Java 模型和 XML 之间序列化和反序列化模型树。模型的某些部分来自扩展 - 创建 JAXB 上下文时,我将模型根类和所有扩展类列为我的上下文类。
这在 Java 端可以正常工作,但会在 Eclipse 端引起问题,我将在下面描述。
我正在使用 Maven 构建整个项目。不是因为我喜欢 Maven(我不喜欢),而是因为 Eclipse 的构建文档非常薄,而且我至少大致了解使用 Maven 构建插件的方法。我一直无法弄清楚如何创建一个直接包含我的普通 Java 核心的 Eclipse 插件项目(无需手动将每个更新的核心构建复制到插件中),但是在对 Apache Felix 进行了很多摆弄之后Maven 插件,我设法获得了以下可用的模块系统:
- 核心模块(封装类型:jar)
- 命令行模块(封装类型:jar,创建可执行jar;与本讨论无关)
- OSGI 模块(封装类型:bundle)
- 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)我有一种不可思议的感觉,我正在以错误的方式解决这个问题。
经过这么长(但我猜是必要的)描述归结为以下问题:
- 如果它确实在实际的 Eclipse 插件中工作,为什么 Eclipse 会抱怨 OSGI 清单?有没有办法修复清单?
- 让 OSGI/Eclipse 方面从普通的 Java Core 获取 JAXB 依赖项是正确的方法吗?
- 如果没有,我怎样才能以 OSGI 方式将 JAXB 依赖项放入插件中?(我还没有找到任何关于如何以及在哪里获得正确的信息,标准实现的最新 OSGI 依赖项(API 的 java.xml.bind 和实现的 com.sun.xml.bind,如果我已经做对了)或 Moxy)我如何确保处理 JAXB 上下文且对 OSGI & Co 一无所知的纯 Java 核心代码能够理解 OSGI 端的注释,如果这带来了自己的独立 JAXB 依赖关系?
- (额外问题)我的 OSGI 包装器项目真的有必要吗?有没有办法让一个 Maven 设置构建一些普通的 Java 模块,并作为最后一个项目,一个 Eclipse 插件直接依赖于早期的模块,以及它们的依赖关系?
解决方案
- Java 11 的系统库不再包含
javax.xml.bind.annotation
。这意味着现在缺少的包必须由插件/捆绑包包含和导出。使用的插件/包javax.xml.bind.annotation
现在必须具有相应的Import-Package
(推荐)或Require-Bundle
(不推荐)条目。 - 不,因为它需要是一个 OSGi 包。Maven 本身无法解析 OSGi 依赖关系,因为例如
Import-Package
语句基于包级别的版本控制,但在 Maven 存储库中只有模块/JAR 级别的版本。 - 当您想在普通 Java 应用程序和像 Eclipse 这样的 OSGi 应用程序中使用相同的 JAR 时,您必须
pom.xml
在META-INF/MANIFEST.MF
. 可以肯定的是,这两个依赖项定义都是正确的,您还必须构建 JAR 两次,例如使用普通 Maven 和 Maven+Tycho。普通 Java 应用程序的构建将从例如 Maven 存储库获取依赖项,而 Eclipse 插件的构建将从 p2 存储库(在您的情况下,例如javax.xml.bind
从Eclipse Orbit)获取来自目标平台的依赖项。 - 不,见 3。
推荐阅读
- vue.js - 如何仅在允许的网站中显示我的 Web 组件
- model-view-controller - 我想要同时进行电子邮件和手机身份验证 web api mvc
- r - 如何将 p.adjust 应用于 R 矩阵中的每一行?
- powershell - 创建到 Microsoft Exchange 的 PowerShell 会话
- r - 通过取消选择不需要的列来按列汇总 R 中的多个列
- python - 在打印字典和添加用户提示以获取嵌套列表值时需要帮助 [Python]
- node.js - Windows 上的 node-odbc 开发和 linux 上的部署
- unity3d - RigidBody2D 和 TileMap Collider 2D 之间的碰撞不能在构建中工作(但在检查器上工作)
- ios - swift 5 ios:如何从 session.dataTask 完成处理程序中获取数据
- javascript - 带有翻译动画的 CSS 背景过滤器