如何基于OSGI Maven bundle构建可部署的单体可执行Java应用?
OSGI多Bundle项目打包可执行单体应用解决方案
可选替代Karaf的打包方案
- Bnd/Bndtools 打包方案:OSGI生态官方推荐的标准工具,通过编写
.bndrun运行描述文件声明OSGI框架、需加载的bundle列表、运行参数,配套Maven插件可直接导出可执行单体jar,无需额外部署容器,是目前最通用的轻量方案。 - Apache Felix Distribution Plugin:适配Felix OSGI框架的打包插件,可直接将Felix内核、所有自定义bundle、运行配置打包为完整的可执行分发包,支持直接生成单体jar,配置逻辑简单。
- Equinox Launcher 方案:若使用Eclipse Equinox作为OSGI内核,可配合Equinox launcher配置与Tycho打包插件生成单体可执行应用,适配Eclipse生态相关的OSGI项目。
- 自定义内嵌OSGI框架打包:自行编写启动类,代码中内嵌启动Felix/Equinox内核,动态加载所有bundle,配合
maven-shade-plugin打fat jar,自由度最高,适合有自定义启动逻辑需求的场景。
通用实现步骤(以Bnd方案为例)
父项目本身打包类型为pom,无法直接生成jar包,建议新增一个专门的distribution子模块用于打包最终的单体应用,步骤如下:
- 在
distribution模块的pom.xml中引入bnd导出插件:
<plugin> <groupId>biz.aQute.bnd</groupId> <artifactId>bnd-export-maven-plugin</artifactId> <version>7.0.0</version> <configuration> <!-- 配置bndrun描述文件路径 --> <bndrun>app.bndrun</bndrun> <!-- 开启可执行jar生成开关 --> <executable>true</executable> </configuration> <executions> <execution> <phase>package</phase> <goals> <goal>export</goal> </goals> </execution> </executions> </plugin>
- 在
distribution模块根目录编写app.bndrun运行描述文件,示例配置如下:
# 指定使用的OSGI框架与版本 -runfw: org.apache.felix.framework;version='[7.0.0,7.0.0]' # 指定运行所需的JDK版本 -runee: JavaSE-11 # 配置所有需要加载的bundle,包含你自己的子项目和第三方依赖bundle -runbundles: \ 你的子项目groupId:子模块1 artifactId;version='[子模块版本号,子模块版本号]',\ 你的子项目groupId:子模块2 artifactId;version='[子模块版本号,子模块版本号]',\ org.apache.felix.scr;version='[2.2.6,2.2.6]' # 用到声明式服务时添加该依赖 # 配置OSGI运行参数,示例为每次启动清空缓存 -runproperties: org.osgi.framework.storage.clean=onFirstInit
- 在父项目根目录执行
mvn clean install,构建完成后可在distribution模块的target目录下得到可执行单体jar,直接执行java -jar 生成的jar包名称.jar即可启动整个OSGI应用。
父项目整合配置注意点
- 只需要在父项目的
modules列表中添加distribution子模块,每次构建父项目时会自动触发所有子模块构建,最终生成单体可执行包,无需修改父项目本身的打包类型。 - 若不想新增子模块,也可以直接将上述打包配置写在Launcher子模块中,直接基于Launcher模块打包生成最终应用。
内容的提问来源于stack exchange,提问作者1288Meow
相关产品推荐
相关产品推荐

