依赖org.eclipse.pde.core的OSGi测试运行失败,icu4j依赖解析异常
我尝试使用来自bnd的aQute.bnd.gradle.TestOSGi任务运行测试,我的库依赖org.eclipse.pde.core,运行时出现如下解析失败报错:
Resolution failed. Capabilities satisfying the following requirements could not be found: [<<INITIAL>>] ⇒ osgi.identity: (osgi.identity=org.eclipse.pde.core) ⇒ [org.eclipse.pde.core version=3.13.200.v20191202-2135] ⇒ osgi.wiring.bundle: (&(osgi.wiring.bundle=org.eclipse.team.core)(bundle-version>=3.2.0)(!(bundle-version>=4.0.0))) ⇒ [org.eclipse.team.core version=3.8.800.v20191122-2107] ⇒ osgi.wiring.bundle: (&(osgi.wiring.bundle=org.eclipse.compare.core)(bundle-version>=3.5.200)(!(bundle-version>=4.0.0))) ⇒ [org.eclipse.compare.core version=3.6.700.v20191122-2107] ⇒ osgi.wiring.package: (&(osgi.wiring.package=com.ibm.icu.text)(version>=3.6.1))
我已经将'com.ibm.icu:icu4j:64.2'加入依赖,还在配置中明确要求启动com.ibm.icu bundle,配置如下:
-runrequires: \ bnd.identity;id='${project.archivesBaseName}',\ bnd.identity;id='junit-jupiter-engine',\ bnd.identity;id='junit-platform-launcher',\ bnd.identity;id='org.eclipse.pde.core',\ bnd.identity;id='com.ibm.icu',\
我查看了icu4j.jar内的MANIFEST文件,内容如下:
Bundle-ManifestVersion: 2 Bundle-Name: ICU4J Bundle-Description: International Components for Unicode for Java Bundle-SymbolicName: com.ibm.icu Bundle-Version: 64.2 Bundle-RequiredExecutionEnvironment: JavaSE-1.7 Main-Class: com.ibm.icu.util.VersionInfo Export-Package: com.ibm.icu.lang,com.ibm.icu.math,com.ibm.icu.number,com.ibm.icu.text,com.ibm.icu.util Automatic-Module-Name: com.ibm.icu
可见该bundle确实导出了com.ibm.icu.text包。我想知道问题出在哪里?我猜测是不是Bundle-RequiredExecutionEnvironment配置导致bundle无法启动(我的测试使用Java 8环境),如果是这个原因,该如何解决该问题?
解答
问题根因
你猜测的Bundle-RequiredExecutionEnvironment(BREE)配置并不是问题根源,Java 8完全向下兼容JavaSE-1.7,BREE最多只会导致bundle启动阶段报错,不会引发你现在遇到的解析阶段依赖不满足错误。
实际问题是你虽然引入了icu4j依赖,也在-runrequires里声明了需要启动该bundle,但bnd的解析器默认没有将maven引入的第三方依赖纳入解析的候选资源池,解析时找不到icu4j的元数据,自然判定com.ibm.icu.text包没有提供者。
解决方案
按优先级选择以下方案即可:
- 优先在你的bnd配置中添加
-runbundles配置,主动将icu4j加入运行时bundle列表,让解析器可以识别到它的导出包信息:
-runbundles: \ com.ibm.icu;version='[64.2,64.3)'
- 检查gradle中icu4j依赖的scope配置,确保它是
runtimeOnly或implementation,而非compileOnly,否则TestOSGi任务默认不会将其纳入运行时依赖范围。 - 如果只是临时排查问题,可以添加
-runsystempackages配置跳过该包的解析检查(不推荐长期使用):
-runsystempackages: com.ibm.icu.text
如果修改后问题仍然存在,可以在bnd配置中添加-resolve: debug开启解析调试日志,直接查看解析器扫描到的所有候选bundle列表,确认icu4j是否被正确纳入解析范围。
内容的提问来源于stack exchange,提问作者Jmini

