部署于EAR中的EJB模块无法注入依赖JAR内CDI Bean如何解决
问题根因
你遇到的注入失败由两个配置问题共同导致:
- Maven EAR插件中单独声明
<jarModule>会覆盖defaultLibBundleDir规则,导致tools.jar被直接放在EAR根目录,而非你预期的lib/路径下,和EJB模块MANIFEST里配置的Class-Path: lib/tools.jar路径不匹配,导致EJB模块类加载路径上找不到tools.jar的类,CDI自然无法发现对应Bean。 - OpenLiberty默认对EAR内不同模块的CDI Bean归档有类加载隔离限制,需要显式配置允许跨模块的CDI Bean访问。
修复步骤
修正Maven打包配置
你不需要单独把tools.jar声明为<jarModule>,只要把它作为EJB模块的普通依赖,Maven EAR插件会自动把它打包到lib/目录下,和MANIFEST的配置匹配:
直接从maven-ear-plugin的<modules>节点中删除如下配置即可:
<jarModule> <groupId>some.group</groupId> <artifactId>tools</artifactId> </jarModule>
如果你确实需要显式声明tools.jar的打包位置,要给<jarModule>加上<bundleDir>配置,强制放到lib目录:
<jarModule> <groupId>some.group</groupId> <artifactId>tools</artifactId> <bundleDir>lib</bundleDir> </jarModule>
配置OpenLiberty允许跨模块CDI Bean发现
有两种可选配置方案,任选其一即可:
方案一:在server.xml中配置全局CDI扫描规则,允许隐式Bean归档和跨模块访问:
<cdi12 enableImplicitBeanArchives="true"/>
方案二:在EAR部署配置中添加类加载配置,共享EAR内的lib目录资源:
<enterpriseApplication id="open-liberty-cup-ear" location="ear.ear" name="open-liberty-cup-ear"> <classloader commonLibraryRef="lib"/> </enterpriseApplication>
验证打包结果
重新打包EAR后确认内部结构符合如下要求:
tools.jar位于EAR的lib/目录下ejb.jar的META-INF/MANIFEST.MF里的Class-Path值为lib/tools.jartools.jar的META-INF目录下存在beans.xml文件,配置为bean-discovery-mode="all"
规范匹配说明
你对CDI 2.0规范的理解是正确的,EJB模块本身可以访问EAR内其他Bean归档的CDI Bean,本次问题是打包路径不匹配和应用服务器默认隔离策略导致的,不属于规范实现偏差。
内容的提问来源于stack exchange,提问作者MaNa
相关产品推荐
相关产品推荐

