OSGI/Karaf容器共享Jar替代嵌入及Bundle异常问题咨询
嘿,你遇到的这个问题在OSGi/Karaf生态里太常见了,你的推测完全正确——类转换异常就是因为两个Bundle各自用自己的类加载器加载了同一个Jar里的类,导致同一个类在JVM里变成了两个不同的类型,自然没法互相转换。我来帮你一步步解决这两个问题:
普通Jar没有OSGi必需的MANIFEST.MF头信息,没法直接在Karaf里安装,咱们有几个简单的办法:
用Karaf自带的Wrap协议快速转换
Karaf内置了wrap机制,可以自动给普通Jar添加OSGi元数据,直接用这条命令安装启动:bundle:install -s wrap:mvn:[groupId]/[artifactId]/[version]把方括号里的内容替换成你Jar的实际坐标就行。如果你的Jar不在Maven仓库,也可以用本地路径:
bundle:install -s wrap:file:///path/to/your.jar手动用bnd工具生成OSGi Bundle
如果你需要更精细的控制(比如指定导出/导入包、Bundle名称等),可以用bnd工具:- 下载bnd工具,创建一个简单的
.bnd文件,内容示例:Bundle-SymbolicName: com.yourcompany.yourjar Bundle-Version: 1.0.0 Export-Package: com.yourcompany.yourjar.* Import-Package: * - 执行命令生成带OSGi元数据的Jar:
bnd wrap your-original.jar -output your-osgi-bundle.jar
之后把生成的Jar放到Karaf的deploy目录,或者用
bundle:install命令安装。- 下载bnd工具,创建一个简单的
你遇到的org.osgi.framework.BundleException: No native code clauses found in the value of Bundle-NativeCode: *错误,是因为这个ServiceMix版本的Jar里的MANIFEST.MF配置了无效的Bundle-NativeCode头——它只写了*,但没有指定具体的本地库文件路径、架构等信息,OSGi容器没法解析。
解决办法有两个:
用Wrap协议覆盖无效的Bundle-NativeCode头
还是用Karaf的wrap命令,在后面加上参数清空这个错误的头:bundle:install -s wrap:mvn:[serviceMix-groupId]/[serviceMix-artifactId]/[version]?Bundle-NativeCode=这样Wrap机制会忽略原Jar里的错误配置,自动生成正确的OSGi元数据。
手动修改MANIFEST.MF
如果你能拿到这个Jar的文件,解压后找到META-INF/MANIFEST.MF,删掉里面的Bundle-NativeCode: *这一行,然后重新打包成Jar,再安装到Karaf里就行。
记得把原来嵌入在两个业务Bundle里的Jar删掉,然后在它们的MANIFEST.MF里添加Import-Package,引入转换后Bundle导出的包。这样两个业务Bundle就会从同一个OSGi Bundle加载类,彻底解决类转换异常的问题。
内容的提问来源于stack exchange,提问作者John Lippson

