寻找提供JavaEL 5.0的OSGi bundle及bnd依赖适配问题咨询
问题背景
使用OSGi Felix实现,自研插件依赖hibernate-validator 8.0.0.Final,通过biz.aQute.bnd:bnd-maven-plugin的bnd-process目标打包后,生成的MANIFEST.MF中包含需求:osgi.contract=JavaEL;version=5.0.0。但OSGi官方文档中仅存在Jakarta Expression Language 5.0或JavaEL 3.0,无JavaEL 5.0版本。
目前发现需在pom.xml添加jakarta.el-api 5.0.0依赖,并在bnd配置的Private-Package中加入jakarta.el;version="5.0.0",但核心应用已提供Jakarta Expression Language 5.0能力,却无法匹配JavaEL 5.0的需求,导致需在各插件中重复声明依赖。
提问
- 这是否是bnd-maven-plugin在javax转jakarta后的能力解析引擎bug?
- 能否避免插件显式引入jakarta-el,利用核心应用已有的同名不同标识的能力?
- 是否存在操作错误?
解答
1. 是否是bnd-maven-plugin的解析bug?
这大概率是bnd处理Jakarta EE契约时的兼容性问题。Hibernate Validator 8.x基于Jakarta EE 9+,依赖的是jakarta.el而非旧的javax.el,但bnd可能仍沿用旧的契约名称映射逻辑,错误地将Jakarta EL 5.0的依赖转换为不存在的JavaEL;version=5.0.0契约需求,而非OSGi官方定义的JakartaExpressionLanguage;version=5.0契约标识。
你可以直接到bnd的官方issue库确认是否已有同类问题,或提交新issue反馈该映射错误。
2. 能否复用核心应用的Jakarta EL能力?
可以,核心思路是修正插件的契约需求,使其匹配核心应用提供的Jakarta EL 5.0契约,而非错误的JavaEL 5.0。具体有两种可行方案:
方案一:在插件bnd配置中强制修正需求
在插件的bnd.bnd文件或pom.xml的bnd-maven-plugin配置里,先移除错误的需求,再手动添加正确的契约依赖:-removeheaders: Require-Capability Require-Capability: osgi.contract;filter:="(&(osgi.contract=JakartaExpressionLanguage)(version>=5.0.0))"配置后插件会直接依赖核心应用提供的Jakarta Expression Language 5.0契约,无需重复引入依赖。
方案二:让核心应用提供兼容契约别名
若核心应用可控,可在其MANIFEST中添加Provide-Capability,同时提供两种契约标识:Provide-Capability: osgi.contract;osgi.contract=JakartaExpressionLanguage;version:Version="5.0", osgi.contract;osgi.contract=JavaEL;version:Version="5.0.0"这样插件的错误需求也能被核心应用匹配,无需修改插件配置。
3. 是否存在操作错误?
你当前添加依赖并打包进Private-Package的操作属于临时 workaround,并非最优解,本质是bnd错误映射导致的。但有几个可优化的操作点:
- 不应将
jakarta.el打包进Private-Package,核心应用已提供该能力,重复打包会引发类加载冲突。 - 未正确开启bnd的Jakarta EE模式,可在bnd配置中添加
jakarta=true属性,让bnd自动适配Jakarta EE契约映射:
该属性会让bnd将Jakarta相关API映射到对应的OSGi Jakarta契约,而非旧的Java EE契约名称。jakarta=true
内容的提问来源于stack exchange,提问作者Vincent C.

