Java17+Spring6+PrimeFaces14迁移遇ClassNotFoundException求助
问题:Java 17/Spring 6/PrimeFaces 14迁移后ClassNotFoundException问题
问题背景
将项目从Java 11迁移至Java 17、Spring 5迁移至Spring 6、RichFaces迁移至PrimeFaces 14(Jakarta)后,启动时出现ClassNotFoundException异常。
异常信息
Exception in thread "main" java.lang.RuntimeException: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityBean': Invocation of init method failed at com.leo.service-ui.Main.main(Main.java:27) Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityBean': Invocation of init method failed at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:222) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:422) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1798) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:600) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:522) at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:337) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:335) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200) at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:975) at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:971) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:625) at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146) at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:754) at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:456) at org.springframework.boot.SpringApplication.run(SpringApplication.java:335) at com.leo.service-ui.Main.main(Main.java:24) Caused by: java.lang.NoClassDefFoundError: jakarta/enterprise/inject/spi/el/ELAwareBeanManager at jakarta.faces.CurrentThreadToServletContext.getFactoryFinder(CurrentThreadToServletContext.java:52) at jakarta.faces.FactoryFinder.getFactory(FactoryFinder.java:257) at jakarta.faces.context.FacesContext.getCurrentInstance(FacesContext.java:872) at com.leo.service-ui.util.FacesUtil.getRequestParameter(FacesUtil.java:28) at com.leo.service-ui.ui.beans.EntityBean.init(EntityBean.java:76) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:569) at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleMethod.invoke(InitDestroyAnnotationBeanPostProcessor.java:457) at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleMetadata.invokeInitMethods(InitDestroyAnnotationBeanPostProcessor.java:401) at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:219) ... 16 more Caused by: java.lang.ClassNotFoundException: jakarta.enterprise.inject.spi.el.ELAwareBeanManager at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641) at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188) at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:525) ... 28 more
项目详情
- Java Version: 17
- Spring Version: 6
- PrimeFaces Version: 14 (Jakarta)
- Build Tool: Maven
pom.xml关键依赖
<dependencies> <!-- Other existing dependencies --> <!-- Jakarta EE dependencies --> <dependency> <groupId>org.primefaces</groupId> <artifactId>primefaces</artifactId> <version>14.0.6</version> <classifier>jakarta</classifier> </dependency> <dependency> <groupId>org.primefaces.extensions</groupId> <artifactId>primefaces-extensions</artifactId> <version>14.0.6</version> </dependency> <!-- <dependency> <groupId>org.apache.myfaces.core</groupId> <artifactId>myfaces-impl</artifactId> <version>4.1.0-RC2</version> </dependency>--> <dependency> <groupId>org.glassfish</groupId> <artifactId>jakarta.faces</artifactId> <version>4.1.1</version> </dependency> <dependency> <groupId>jakarta.el</groupId> <artifactId>jakarta.el-api</artifactId> <version>6.0.1</version> </dependency> <dependency> <groupId>org.jboss.weld.servlet</groupId> <artifactId>weld-servlet-shaded</artifactId> <version>5.1.3.Final</version> </dependency> <dependency> <groupId>jakarta.enterprise</groupId> <artifactId>jakarta.enterprise.cdi-api</artifactId> <version>4.1.0</version> </dependency> <dependency> <groupId>jakarta.platform</groupId> <artifactId>jakarta.jakartaee-api</artifactId> <version>10.0.0</version> <scope>provided</scope> </dependency> </dependencies>
异常触发代码
public class FacesUtil { public static String getRequestParameter(String paramName) { FacesContext context = FacesContext.getCurrentInstance(); // Exception occurs here Map<String, String> params = context.getExternalContext().getRequestParameterMap(); return params.getOrDefault(paramName, null); } }
已尝试操作
- 确认pom.xml中包含所有必要的Jakarta EE依赖
- 确保存在weld-servlet-shaded依赖
- 添加了scope为provided的jakarta.jakartaee-api依赖
问题分析与解决方案
成因
- CDI依赖版本不兼容:
jakarta.enterprise.cdi-api 4.1.0对应CDI 4.1规范,其中ELAwareBeanManager类已被移除;而weld-servlet-shaded 5.1.3.Final是CDI 4.0的实现,二者版本不匹配导致类找不到。 - FacesContext调用时机错误:在Spring Bean的初始化方法(
init)中调用FacesContext.getCurrentInstance(),此时JSF上下文尚未初始化,触发底层CDI类加载,暴露了依赖冲突问题。
解决步骤
统一CDI依赖版本
将jakarta.enterprise.cdi-api版本改为与Weld 5.x兼容的4.0.1(Weld 5.x对应CDI 4.0),修改pom.xml:<dependency> <groupId>jakarta.enterprise</groupId> <artifactId>jakarta.enterprise.cdi-api</artifactId> <version>4.0.1</version> </dependency>修复FacesContext调用时机
FacesContext.getCurrentInstance()仅在JSF请求处理周期内有效,不能在Spring Bean初始化阶段调用。替代方案:- 通过Spring注入
HttpServletRequest获取请求参数:@Autowired private HttpServletRequest request; public String getRequestParameter(String paramName) { return request.getParameter(paramName); } - 若需在JSF托管Bean中初始化,改用JSF的
@PostConstruct注解(而非Spring的初始化方法)。
- 通过Spring注入
清理冗余依赖
Spring Boot项目无需依赖jakarta.jakartaee-api(Spring Boot已包含必要的Jakarta EE子集),建议移除该依赖避免版本冲突。
迁移额外注意事项
- 确保所有代码中API引用从
javax.*替换为jakarta.*(如javax.faces→jakarta.faces)。 - Spring 6与PrimeFaces 14均基于Jakarta EE 10,需保证所有相关依赖都使用Jakarta命名空间版本。
- Spring Boot中使用JSF需配置
spring-boot-starter-faces,或手动注册FacesServlet并配置初始化参数,确保JSF上下文正确初始化。
内容的提问来源于stack exchange,提问作者sparkey
相关产品推荐
相关产品推荐

