BndTools教程:如何添加非OSGi格式JAR包?
我之前在OSGi项目里引入第三方普通JAR时也踩过这个坑!普通JAR包没有OSGi所需的元数据(比如MANIFEST.MF里的Export-Package、Bundle-SymbolicName等),所以Felix容器根本没法识别它的依赖关系,就会抛出你遇到的那种BundleException依赖缺失错误。
下面给你几个靠谱的解决思路,按优先级推荐:
1. 直接使用现成的OSGi兼容版jcraft包
先去Maven中央仓库搜一下有没有已经打包成OSGi Bundle的jcraft(比如JSch,jcraft最常用的就是这个)。很多流行的库都有社区维护的OSGi版本,你可以直接在项目的依赖里引入这类Bundle,比如:
<dependency> <groupId>com.jcraft</groupId> <artifactId>jsch</artifactId> <version>0.1.55</version> <classifier>osgi</classifier> </dependency>
引入后直接把这个OSGi Bundle丢进Felix容器,它自带完整的元数据,容器能正常解析依赖。
2. 把普通JAR转换成OSGi Bundle
如果找不到现成的OSGi版本,就用bnd工具手动把普通JAR转成Bundle。推荐用Maven的maven-bundle-plugin来做,在你的项目pom.xml里添加插件配置:
<build> <plugins> <plugin> <groupId>org.apache.felix</groupId> <artifactId>maven-bundle-plugin</artifactId> <version>5.1.9</version> <extensions>true</extensions> <configuration> <instructions> <Bundle-SymbolicName>com.jcraft.jsch</Bundle-SymbolicName> <Bundle-Version>0.1.55</Bundle-Version> <Export-Package>com.jcraft.jsch.*</Export-Package> <Import-Package>*</Import-Package> </instructions> </configuration> </plugin> </plugins> </build>
配置好后执行mvn package,就能生成带OSGi元数据的Bundle JAR,替换原来的普通JAR丢进容器就行。
3. 将jcraft设为OSGi系统包
如果上面两种方法都不想用,还可以把jcraft的包加到OSGi系统的导出包列表里,让容器把它当作系统级别的包来处理。在Felix的config.ini里添加以下配置:
org.osgi.framework.system.packages.extra=com.jcraft.jsch,com.jcraft.jsch.*
然后把jcraft的普通JAR放到Felix的lib目录下,容器启动时会自动加载并导出这些包,你的应用Bundle就能正常依赖了。
为什么普通JAR不行?
OSGi容器是基于模块化的,每个Bundle都需要通过MANIFEST.MF里的元数据声明自己导出的包、依赖的包。普通JAR没有这些元数据,容器无法知道它能提供哪些包,所以你的应用Bundle请求依赖时,容器就会抛出“missing requirement”的错误。
内容的提问来源于stack exchange,提问作者Amrith Raj Herle

