OSGI 包中的依赖性问题
Trouble with dependencies in an OSGI bundle
我有一个运行良好的 OSGI 包,我添加了一个 maven
依赖项 unirest
轻量级 HTTP
库,当部署到 serviceMix
我获得 missing requirement
:
filter:="(osgi.wiring.package=com.mashape.unirest.http)"
当然我在我的包中使用那个包,但就 serviceMix 而言,那个库只是 类 在我的 classpath
就像我自己的 类
我想我在这里遗漏了一些东西
我知道可以 embed
一个库,但我不明白为什么需要任何额外的操作?这与仅将该库添加为 maven dependency
有何不同
非常感谢 articles/documentation 的任何答案和指示
maven 和 osgi 处理依赖关系的方式不同。
Maven 将依赖关系视为单个 classpath/classloader,其中来自每个 jar 的 classes 可以访问来自每个其他 jar 的 classes。
这是主要应用程序的历史记录,也是 Maven 运行单元测试的方式。
在 osgi run-time 环境中,每个包都有自己的 classloader,默认情况下,只能访问嵌入在自己包中的 classes 和 jars。
每个包中的 classes 是隔离的,除非包从一个包中导出并导入到另一个包中。
maven bundle 插件试图弥补这一差距。仅仅给maven添加依赖是不够的,还必须告诉maven bundle plugin如何打包部署。选项是 1) 将依赖项嵌入到您的包中,或 2) 将依赖项部署为单独的包。
maven bundle 插件默认为选项 2:导入所有内容。
为了更好地理解依赖项的导出,我建议查看 bundle jar 中的清单文件。 (META-INF/manifest.mf)
我刚刚在maven central上查看了unirest jar,发现清单中没有导出包。事实上 unirest 没有包头,所以它不是 osgi 包。
错误信息
缺少要求:过滤器:="(osgi.wiring.package=com.mashape.unirest.http)"
表示您的包正在尝试导入包,但 servicemix 没有包导出它。
为了更好地理解这一点,我建议查看 bundle jar 中的清单文件。 (META-INF/manifest.mf) 我预计它将包含 com.mashape.unirest.http 的导入。还要查看 servicemix 以查看是否有任何内容导出它:
来自 try 的命令:exports | grep com.mashape.unirest.http
我希望您会发现没有导出它的包。
我建议您配置 maven bundle 插件以嵌入 unirest 而不是导入它。像这样:
<Embed-Dependency>unirest-java</Embed-Dependency>
(如果您已有 Embed-Dependency 配置,则需要合并它们。)
另一种方法是将 unirest-java 打包部署为一个包。
这可能就像将它复制到部署文件夹一样简单:
https://karaf.apache.org/manual/latest/#_wrap_deployer
这将具有共享 unirest-java.
的优势
最后,如果 unirest 自己进行 class 加载,那么这可能会与 osgi 不兼容。
我有一个运行良好的 OSGI 包,我添加了一个 maven
依赖项 unirest
轻量级 HTTP
库,当部署到 serviceMix
我获得 missing requirement
:
filter:="(osgi.wiring.package=com.mashape.unirest.http)"
当然我在我的包中使用那个包,但就 serviceMix 而言,那个库只是 类 在我的 classpath
就像我自己的 类
我想我在这里遗漏了一些东西
我知道可以 embed
一个库,但我不明白为什么需要任何额外的操作?这与仅将该库添加为 maven dependency
非常感谢 articles/documentation 的任何答案和指示
maven 和 osgi 处理依赖关系的方式不同。 Maven 将依赖关系视为单个 classpath/classloader,其中来自每个 jar 的 classes 可以访问来自每个其他 jar 的 classes。 这是主要应用程序的历史记录,也是 Maven 运行单元测试的方式。
在 osgi run-time 环境中,每个包都有自己的 classloader,默认情况下,只能访问嵌入在自己包中的 classes 和 jars。 每个包中的 classes 是隔离的,除非包从一个包中导出并导入到另一个包中。
maven bundle 插件试图弥补这一差距。仅仅给maven添加依赖是不够的,还必须告诉maven bundle plugin如何打包部署。选项是 1) 将依赖项嵌入到您的包中,或 2) 将依赖项部署为单独的包。 maven bundle 插件默认为选项 2:导入所有内容。
为了更好地理解依赖项的导出,我建议查看 bundle jar 中的清单文件。 (META-INF/manifest.mf) 我刚刚在maven central上查看了unirest jar,发现清单中没有导出包。事实上 unirest 没有包头,所以它不是 osgi 包。
错误信息 缺少要求:过滤器:="(osgi.wiring.package=com.mashape.unirest.http)" 表示您的包正在尝试导入包,但 servicemix 没有包导出它。 为了更好地理解这一点,我建议查看 bundle jar 中的清单文件。 (META-INF/manifest.mf) 我预计它将包含 com.mashape.unirest.http 的导入。还要查看 servicemix 以查看是否有任何内容导出它: 来自 try 的命令:exports | grep com.mashape.unirest.http 我希望您会发现没有导出它的包。
我建议您配置 maven bundle 插件以嵌入 unirest 而不是导入它。像这样:
<Embed-Dependency>unirest-java</Embed-Dependency>
(如果您已有 Embed-Dependency 配置,则需要合并它们。)
另一种方法是将 unirest-java 打包部署为一个包。 这可能就像将它复制到部署文件夹一样简单: https://karaf.apache.org/manual/latest/#_wrap_deployer 这将具有共享 unirest-java.
的优势最后,如果 unirest 自己进行 class 加载,那么这可能会与 osgi 不兼容。