如何从Maven工件更新运行中的Apache Felix Bundle
我之前在OSGi项目里也遇到过一模一样的需求——不想每次都等5分钟重启Pax Runner,只想快速更新自己的bundle。给你分享几个实操性强的方案:
方案1:修改你的项目POM,让
mvn install直接生成OSGi Bundle 这是最省心的长期方案,从根源上解决问题,以后每次构建出来的都是合法的Bundle,不需要额外转换步骤。
你只需要在项目的pom.xml中添加maven-bundle-plugin,并开启extensions(让Maven把bundle当成一种合法的打包类型):
<build> <plugins> <plugin> <groupId>org.apache.felix</groupId> <artifactId>maven-bundle-plugin</artifactId> <version>4.2.1</version> <!-- 建议用最新稳定版 --> <extensions>true</extensions> <configuration> <instructions> <!-- 必须配置的核心OSGi头 --> <Bundle-SymbolicName>${project.groupId}.${project.artifactId}</Bundle-SymbolicName> <Bundle-Version>${project.version}</Bundle-Version> <!-- 按需配置:导出你的项目需要对外暴露的包 --> <Export-Package>com.your.company.yourproject.api.*</Export-Package> <!-- 自动导入所有依赖的包,按需调整 --> <Import-Package>*;resolution:=optional</Import-Package> </instructions> </configuration> </plugin> </plugins> </build>
配置完成后,执行mvn clean install,此时本地Maven仓库中存储的就不再是普通JAR,而是带有完整OSGi Manifest的Bundle了。之后你直接在运行的Felix环境中执行:
felix:update com.your.company.yourproject
(这里的参数是你配置的Bundle-SymbolicName),Felix会自动从本地Maven仓库拉取最新的Bundle并更新,完全不需要重启整个环境。
方案2:将已有的普通JAR转换为Bundle(无需修改原项目)
如果因为各种原因你不能修改原项目的POM(比如是第三方JAR,或者不想改动现有构建流程),可以用maven-bundle-plugin的单独命令来转换本地仓库中的普通JAR:
- 首先找到本地Maven仓库中目标JAR的路径,比如:
~/.m2/repository/com/your/project/1.0.0/project-1.0.0.jar - 执行转换命令,生成Bundle:
mvn org.apache.felix:maven-bundle-plugin:bundle \ -Dbundle.source=~/.m2/repository/com/your/project/1.0.0/project-1.0.0.jar \ -Dbundle.symbolicName=com.your.project \ -Dbundle.version=1.0.0 \ -Dbundle.exportPackage=com.your.project.*
这个命令会在当前目录生成一个带有OSGi Manifest的Bundle JAR(比如project-1.0.0-bundle.jar)
3. 将转换后的Bundle安装到本地Maven仓库,这样Felix就能找到它:
mvn install:install-file \ -Dfile=./project-1.0.0-bundle.jar \ -DgroupId=com.your.project \ -DartifactId=project \ -Dversion=1.0.0 \ -Dpackaging=bundle \ -Dclassifier=bundle
完成后同样可以用felix:update com.your.project来更新Bundle。
关键注意点
- OSGi Bundle的核心是Manifest文件,必须包含
Bundle-SymbolicName和Bundle-Version这两个必填头,否则Felix无法识别为合法Bundle。 - 使用
felix:update时,要确保命令中的bundle名称和你生成的Bundle的Bundle-SymbolicName完全一致,大小写敏感。 - 如果你的项目依赖其他Bundle,记得在
Import-Package中正确配置依赖,避免运行时ClassNotFound异常。
内容的提问来源于stack exchange,提问作者62mkv
相关产品推荐
相关产品推荐

