我在尝试安装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"
Run Code Online (Sandbox Code Playgroud)
我已在此博客上遵循此类问题的诊断程序.
以下是我的发现:该捆绑com.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)"
Run Code Online (Sandbox Code Playgroud)
在我的OSGi中唯一具有此使用约束的包是com.springsource.org.apache.commons.logging,它具有以下指令:
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
Run Code Online (Sandbox Code Playgroud)
在这一点上,我陷入困境,因为我无法弄清楚问题是什么以及如何解决它虽然从我上面提供的应该是清楚的,但不是我:(
有任何想法吗...?
Ang*_*jpt 13
这很可能与'import-what-you-export'有关.
一个uses约束指出:"如果你要导入这个包,最好确保你使用的是我在同一个软件包",这不仅意味着软件包的版本,但相同的包,由同捆出口.你的第二个包导出logging和logging.impl包,说"如果你想使用logging.impl,使用logging我做的相同",它也恰好导出一个.这意味着任何想要导入的人也logging.impl 必须logging从您的包中导入,因为它无法连接到任何其他logging包.如果logging框架中有另一个副本,这可能会导致问题,这可能会在之前得到解决.
解决这个问题的最简单方法可能是添加logging到Import-Package第二个包中.这样,您可以选择使用哪个包到框架.
在一个不相关的注释,摆脱所有这些";resolution:=optional语句,除非你的代码可以真正适用于某些包不可用的情况.我很惊讶你的捆绑可以在没有javax.servlet可用的情况下工作.
检测(Eclipse)OSGI错误"使用冲突"解决具有冲突的大型捆绑树是一项繁琐的工作.最容易解决的错误是"缺少约束".这只是一个缺少的bundle或类,错误明确指出缺少哪个java包/ bundle.我想要关注的是名为"uses-conflict"的神秘的OSGI错误消息.Equinox OSGI工具不提供有关创建版本冲突的软件包名称的大量信息.有很多论文解释了如何解决冲突,然而,他们都没有展示如何找到快速冲突的包.这是一种识别哪个包+版本导致冲突的方法.我们将从一些想象的项目开始:开发人员编写了一个eclipse插件+几个包(JAR).该插件主要包含UI代码,JAR主要包含共享/可重用逻辑.开发人员将它们全部打包到Eclipse功能中并尝试安装它.由于"使用冲突",插件无法启动.
你有一个插件.您安装但由于"使用冲突"关闭日食而无法启动.通过命令行(linux)重新运行eclipse:
./eclipse -console -consoleLog -data /tmp/eclipseTest/workspace/ -clean
Run Code Online (Sandbox Code Playgroud)
(win32用户应该调用eclipse.exe ofcourse)这个命令将带来我们以后需要的osgi控制台.当eclipse加载完成后,切换回eclipse命令行窗口.你应该看到"osgi>"命令提示符(如果没有按两次Enter键)找到你的插件/包的Java包.假设它在osgi控制台中运行命名为com.A,B,C,D和E:
osgi> ss com.A
id State Bundle
7 INSTALLED com.A
osgi> start 7
Run Code Online (Sandbox Code Playgroud)
org.osgi.framework.BundleException:无法解析包"com.A [7]".原因:包使用冲突:Require-Bundle:com.B; bundle-version ="0.0.0"at org.eclipse.osgi.framework.internal.core.AbstractBundle.getResolverError ... more stack here ...
现在我们知道com.A依赖于bundle com.B和com.B的bundle有冲突.原因当然是营养用途冲突.(旁注:实际冲突可能会进一步隐藏:在com.B所依赖的其他一些包中,但我们暂时忽略它)我们希望得到的理想状态是:
osgi> ss com.A
Framework is launched.
id State Bundle
7 ACTIVE com.A
Run Code Online (Sandbox Code Playgroud)
但我们还没有.
所以我们知道bundle com.B是有问题的.我们可以通过运行看到它尝试加载(但失败)的导入列表
osgi> bundle 10
Run Code Online (Sandbox Code Playgroud)
(10是我们的com.B包从OSGI容器中获取的随机包id.只需在osgi控制台中运行:"ss com.B"以查找其包ID)
专注于"导入 - 包"部分.把它复制到某个地方.在向eclipse框架安装插件时,它实际上是解压缩到eclipse的插件目录中.打开文件资源管理器并转到/ plugins.找到"坏"包的目录(用例"使用冲突")它可能被命名为com.B. [version_or_timestamp].
深入到META-INF目录.编辑manifest.mf:首先清理Import-packages部分(将该部分剪切粘贴到记事本)
重启eclipse(Ctrl + C退出osgi控制台运行eclipse然后重新运行)现在eclipse应该说bundle是"ACTIVE".如果它没有以活动模式启动,它可能会遇到Missing-Constraint错误.这很容易解决,因为错误信息非常丰富,但这不是重点.
在使用冲突重新弹出之前:开始将该清单中的Import-packages部分重新填充到其原始状态.一次做一个java包,这样你可以确定哪个更改导致"使用冲突"
在记事本中编辑manifest.mf时,请确保在第71列按Enter键,下一行以单个空格开头.您可能已经注意到,清单具有您必须遵循的独特新线结构.
重启eclipse(在osgi控制台中按Ctrl + C然后重新运行).
通过运行osgi命令"ss com.A"重新测试bundle状态,尝试"启动com.A"并查看是否有任何错误.
每个manifest.mf之后重新启动eclipse,如上所述.
将错误的java导入添加到manifest.mf后,您将看到该包仅标记为"已解决"(而非活动).让我们假设你发现破解捆绑包的第一个java包是javax.xml.bind.在OSGI控制台上运行:"package javax.xml.bind",您应该看到已解析的OSGI包的列表+该命名空间的版本+用法.如果您有多个提供程序(即多个版本 - 它的树.查看其根目录),您可能需要更改原始包并强制它导入特定版本(通过使用Import中的"version"指令-Package部分.例如javax.xml.bind; version ="[2.1,3)" 这告诉osgi搜索范围)一般来说,如果你编写一个OSGI包或一个Eclipse插件,最好的做法是尽可能明确指定一个Import版本范围(而不是使用默认值,即0.0.0或任何版本) )在Import-package标头中.同样的规则也适用于uses:=有时在Import-Package头中使用的指令.
同样适用于Require-Bundle标头:最好使用"bundle-version"OSGI指令来确保获得您期望的版本.如果Maven在构建过程中使用它更重要,因为它允许maven正确计算版本依赖性(特别是如果使用Felix maven-bundle-plugin)
另一个问题是有时你在bundle的清单中要求:Import-Package:javax.xml.bind; version ="[2.1.9,3)"但由于某些原因这不能满足.如果可能,您可以将版本范围扩展到更宽的范围.
解决OSGI冲突后,请不要忘记相应地编辑原始构建清单/脚本.
一边评论:您也可以尝试运行"eclipse.exe -clean",这可能会正确地重新计算捆绑依赖关系并让您的插件启动,但这不是一个长期的解决方案.
| 归档时间: |
|
| 查看次数: |
18280 次 |
| 最近记录: |