Payara 5.x Beta中使用Omnifaces @Eager触发WeldListener创建失败问题
首先,你的问题核心是Payara 5 Beta 下的类加载冲突 + CDI 版本适配问题,结合你坚持使用 <class-loader delegate="false"/> 的配置,以下是具体分析和解决步骤:
为什么Payara 4正常但Payara 5报错?
Payara 4.x 内置的是 CDI 1.2(对应 Weld 2.x),而 Payara 5.x 升级到了 CDI 2.0(对应 Weld 3.x)。你手动引入了 weld-core-bom 3.0.1.Final,再加上 delegate=false 的类加载配置,导致应用类加载器优先加载你自己引入的 Weld 类,和 Payara 5 内置的 Weld 版本产生冲突——这种冲突在 @Eager 触发的早期CDI初始化阶段(比普通Bean初始化更早)暴露出来,直接导致 WeldListener 创建失败,应用无法启动。
同时,你使用的 Omnifaces 2.6.7 主要适配 CDI 1.x,虽然部分兼容 CDI 2.0,但在 @Eager 这种涉及容器启动初期的场景下,容易触发兼容性问题。
解决方案(无需修改delegate=false配置)
1. 移除手动引入的Weld依赖
Payara 作为 Java EE 服务器,已经内置了完整的 CDI 实现(Weld),手动引入 Weld BOM 完全没必要,反而会引发类加载冲突。直接删除这段依赖:
<dependency> <groupId>org.jboss.weld</groupId> <artifactId>weld-core-bom</artifactId> <version>3.0.1.Final</version> <type>pom</type> </dependency>
2. 升级Omnifaces到CDI 2.0兼容版本
Omnifaces 3.x 专门为 CDI 2.0/Java EE 8 设计,能完美适配 Payara 5.x。把 Omnifaces 依赖升级到最新的 3.x 版本(比如 3.14):
<dependency> <groupId>org.omnifaces</groupId> <artifactId>omnifaces</artifactId> <version>3.14</version> </dependency>
3. 升级Java EE API到8.0版本
Payara 5.x 是 Java EE 8 兼容服务器,把 javaee-web-api 从 7.0 升级到 8.0,确保API版本和服务器兼容:
<dependency> <groupId>javax</groupId> <artifactId>javaee-web-api</artifactId> <version>8.0</version> </dependency>
修改后的完整依赖配置
<dependency> <groupId>org.primefaces</groupId> <artifactId>primefaces</artifactId> <version>6.1</version> </dependency> <dependency> <groupId>org.eclipse.persistence</groupId> <artifactId>eclipselink</artifactId> <version>2.6.5</version> </dependency> <dependency> <groupId>org.javamoney</groupId> <artifactId>moneta</artifactId> <version>1.1</version> </dependency> <dependency> <groupId>javax</groupId> <artifactId>javaee-web-api</artifactId> <version>8.0</version> </dependency> <dependency> <groupId>org.omnifaces</groupId> <artifactId>omnifaces</artifactId> <version>3.14</version> </dependency>
额外注意点
- EclipseLink 2.6.5 是兼容 Java EE 8 的,所以不需要修改版本;
- 保持
glassfish-web.xml的delegate=false配置没问题,但要注意不要引入服务器已经内置的核心容器依赖(比如Weld、CDI API、JSF API等),否则很容易触发类加载冲突; - 如果你后续遇到
Money类型的持久化问题,可以检查 EclipseLink 是否需要额外的转换器配置,但这和当前的启动异常无关。
内容的提问来源于stack exchange,提问作者Kalle Richter

