OSGI(bnd项目)Java8迁移至Java9遇Require-Capability版本兼容问题
嘿,我刚帮好几个开发者搞定过类似的Java 9+OSGi迁移坑,你碰到的这个org.apache.felix.gogo.command启动失败问题,本质是旧版本组件没适配Java 9引入的JPMS模块系统,给你几个落地的解决方向:
1. 立刻升级Felix Gogo组件到兼容版本
你用的org.apache.felix.gogo.command-1.0.2是非常老的版本,完全没考虑Java 9的模块规则。直接把Gogo全家桶(command、runtime、shell)都升级到1.1.0及以上版本(推荐1.1.2,稳定且适配JPMS),这些新版本都添加了Automatic-Module-Name声明,能和Java 9的模块系统和平共处。
在你的bnd配置文件(比如bnd.bnd)里更新依赖:
-buildpath: \ org.apache.felix:org.apache.felix.gogo.command:1.1.2,\ org.apache.felix:org.apache.felix.gogo.runtime:1.1.2,\ org.apache.felix:org.apache.felix.gogo.shell:1.1.2
如果用Maven,记得同步更新maven-bnd-plugin里的依赖版本。
2. 给bnd加上Java 9兼容配置
bnd需要明确知道你要适配Java 9,不然生成的bundle会和JPMS冲突。在bnd文件里加这几行:
-java-version: 9 --module-info: auto # 要是某些旧组件还依赖Java内部API(尽量避免,实在没办法再加) --add-exports: java.base/sun.nio.ch=ALL-UNNAMED
如果是Maven项目,把这段配置塞进maven-bnd-plugin的<bnd>标签里就行,同时记得把bnd插件本身升级到6.4.0及以上版本——新版本对JPMS的支持完善很多。
3. 排查Import-Package未解析的根源
错误里提到的org.apache.felix.service.command导入失败,除了升级组件,还要检查两点:
- 你的Felix Framework版本太旧?至少要升到5.6.10及以上,旧框架在Java 9下会搞不定模块加载。
- 启动顺序有没有问题?
org.apache.felix.gogo.runtime必须先于gogo.command启动,因为前者才是org.apache.felix.service.command包的提供者。
4. 应急绕过方案(不推荐长期用)
如果有些老组件实在没法升级,临时可以在JVM启动参数里加这些,让JPMS放宽限制:
--add-modules ALL-SYSTEM --add-exports java.base/jdk.internal.reflect=ALL-UNNAMED --add-opens java.base/java.lang=ALL-UNNAMED
但这只是权宜之计,长期来看还是要升级组件,不然以后迁Java 11、17会更麻烦。
最后再啰嗦一句:迁移时尽量把所有依赖的OSGi bundle都升级到Java 9+兼容版,bnd工具也用最新稳定版,能省超多麻烦!
内容的提问来源于stack exchange,提问作者Azbesciak

