Osgi 包使用冲突:启动包时导入包
尝试安装htmlunit捆绑包时出现以下错误:Osgi 包使用冲突:启动包时导入包,osgi,Osgi,尝试安装htmlunit捆绑包时出现以下错误: com.springsource.com.gargoylesoftware.htmlunit_2.6.0 [370] could not be resolved. Reason: Package uses conflict: Import-Package: org.apache.commons.logging.impl; version="1.1.1" 我已在上遵循了此类问题的诊断程序 以下是我的发现: bundlecom.spring
com.springsource.com.gargoylesoftware.htmlunit_2.6.0 [370] could not be resolved.
Reason: Package uses conflict:
Import-Package: org.apache.commons.logging.impl; version="1.1.1"
我已在上遵循了此类问题的诊断程序
以下是我的发现:
bundlecom.springsource.com.gargoylesoftware.htmlunit_2.6.0
具有以下说明:
Import-Package: \
org.apache.commons.logging;version="[1.1.1, 2.0.0)",\
org.apache.commons.logging.impl;version="[1.1.1, 2.0.0)"
Export-Package: \
org.apache.commons.logging;version="1.1.1",\
org.apache.commons.logging.impl;version="1.1.1";\
uses:="javax.servlet,
org.apache.avalon.framework.logger,
org.apache.commons.logging,
org.apache.log,
org.apache.log4j"
Import-Package: \
javax.servlet;version="[2.1.0, 3.0.0)";resolution:=optional,\
org.apache.avalon.framework.logger;version="[4.1.3, 4.1.3]";resolution:=optional,\
org.apache.log;version="[1.0.1, 1.0.1]";resolution:=optional,\
org.apache.log4j;version="[1.2.15, 2.0.0)";resolution:=optional
在我的OSGi中只有com.springsource.org.apache.commons.logging
,它有以下说明:
Import-Package: \
org.apache.commons.logging;version="[1.1.1, 2.0.0)",\
org.apache.commons.logging.impl;version="[1.1.1, 2.0.0)"
Export-Package: \
org.apache.commons.logging;version="1.1.1",\
org.apache.commons.logging.impl;version="1.1.1";\
uses:="javax.servlet,
org.apache.avalon.framework.logger,
org.apache.commons.logging,
org.apache.log,
org.apache.log4j"
Import-Package: \
javax.servlet;version="[2.1.0, 3.0.0)";resolution:=optional,\
org.apache.avalon.framework.logger;version="[4.1.3, 4.1.3]";resolution:=optional,\
org.apache.log;version="[1.0.1, 1.0.1]";resolution:=optional,\
org.apache.log4j;version="[1.2.15, 2.0.0)";resolution:=optional
在这一点上,我被卡住了,因为我不知道问题是什么以及如何解决它,尽管从我上面提供的内容来看,应该是清楚的,但对我来说不是:(
有什么想法吗?这很可能与“导入导出的内容”有关
使用
约束状态“如果要导入此包,最好确保使用与我相同的包”,这不仅意味着包的版本,还意味着由相同包导出的相同包。
您的第二个捆绑包导出日志记录
和日志记录.impl
包,说明“如果要使用日志记录.impl
,请使用与我相同的日志记录
”这意味着任何想要导入logging.impl
的人也必须从您的包中导入logging
,因为它不能连接到任何其他logging
包。
如果框架中有另一个日志记录
副本,这会导致问题,这可能会更早得到解决
解决这一问题的最简单方法可能是将日志记录
添加到第二个捆绑包的导入包
。这样,您就可以选择使用哪个包了
另一个不相关的注意事项是,去掉所有那些“resolution:=可选的语句,除非你的代码真的可以在某些包不可用的情况下工作。我会非常惊讶你的包可以在没有javax.servlet
可用的情况下工作。检测(Eclipse)OSGI错误“使用冲突”
解决具有冲突的大型捆绑树是一项乏味的工作。
最容易解决的错误是“缺少约束”。这只是缺少一个包或类,错误明确指出缺少哪个java包/包。
我想重点关注的是神秘的OSGI错误消息“usesconflict”。
Equinox OSGI工具没有提供太多关于导致版本冲突的包名的信息。有很多文章解释了如何解决冲突,但是没有一篇文章说明如何快速找到冲突的包。
下面是一种方法,用于识别导致冲突的软件包+版本。
我们将从一个虚构的项目开始:一个开发人员编写了一个eclipse插件+几个捆绑包(JAR)。
插件主要包含UI代码,JAR主要包含共享/可重用逻辑。
开发人员将它们全部打包到Eclipse特性中,并尝试安装它。
由于“使用冲突”,插件无法启动
您有一个插件。您已安装,但由于“使用冲突”而无法启动
接近日食。
通过命令行(linux)重新运行eclipse:
(win32用户当然应该调用eclipse.exe)
这个命令将启动我们稍后需要的osgi控制台。
eclipse加载完成后,切换回eclipse命令行窗口。您应该会看到“osgi>”命令提示符(如果没有,请按Enter键两次)
找到插件/捆绑包的Java包。假设它的名称为com.A、B、C、D和E
在osgi控制台中运行:
osgi> ss com.A
id State Bundle
7 INSTALLED com.A
osgi> start 7
org.osgi.framework.BundleException:无法解析捆绑包“com.A[7]”。原因:包使用冲突:需要捆绑包:com.B;捆绑包版本=“0.0.0”
在org.eclipse.osgi.framework.internal.core.AbstractBundle.GetResolveError…这里有更多的堆栈
现在我们知道com.A依赖于bundle com.B的bundle与com.B存在冲突。原因当然是冲突。(旁注:实际上冲突可能被隐藏得更深:在com.B依赖的其他bundle中,但现在让我们忽略这一点)
我们希望达到的理想状态是:
osgi> ss com.A
Framework is launched.
id State Bundle
7 ACTIVE com.A
但我们还没有做到
所以我们知道bundle com.B是有问题的。
我们可以看到它试图通过运行来加载(但失败)的导入列表
osgi> bundle 10
(10是我们的com.B包从OSGI容器中获得的随机包id。只需在OSGI控制台中运行:“ss com.B”即可找到其包id)
- 关注“导入包”部分。将其复制到某个地方。
将插件安装到eclipse框架时,它实际上被解压缩到eclipse的插件目录中。打开文件资源管理器并转到/plugins。找到“坏”包的目录(即“使用冲突”的目录),它可能会被命名为com.B.[版本\或\时间戳]
- 深入到META-INF目录。编辑manifest.mf:首先清理导入包部分(将该部分剪切粘贴到记事本)
- 重新启动eclipse(Ctrl+C退出osgi控制台中运行的eclipse,然后重新运行)
现在eclipse应该说bundle是“ACTIVE”的。如果它不是在ACTIVE模式下启动的,它可能会遇到一个缺少约束的错误。这很容易解决,因为错误信息非常丰富,但这不是本文的重点
- 直到使用冲突重新弹出:开始将该清单中的导入包部分重新填充到其原始状态。一次执行一个java包,以便您可以确定导致“使用冲突”的更改点
- 在记事本中编辑manifest.mf时,请确保在第71列按Enter键,并且下一行以单个空格开头。正如您可能已经注意到的,清单具有您必须遵循的唯一新行结构
- 重新启动eclipse(在osgi控制台中按Ctrl+C,然后重新运行)