Wildfly 30部署EJB 2.0报错:找不到EJBObject.isIdentical方法
问题
我们有一个基于EJB 2.0的J2EE Web应用,在Wildfly 10.0环境中运行正常。升级至最新稳定版Wildfly 30.0.0后,部署EJB 2.0时出现方法未找到错误,堆栈信息如下:
2023-12-11 18:27:57,641 INFO [org.jboss.weld.Version] (MSC service thread 1-3) WELD-000900: 5.1.2 (Final) 2023-12-11 18:27:57,683 WARN [org.jboss.as.ee] (MSC service thread 1-8) WFLYEE0007: Not installing optional component com.comp.api.service.soap.compAxisServlet due to an exception (enable DEBUG log level to see the cause) 2023-12-11 18:27:57,692 WARN [org.jboss.as.ee] (MSC service thread 1-7) WFLYEE0007: Not installing optional component org.apache.axis.transport.http.AxisServlet due to an exception (enable DEBUG log level to see the cause) 2023-12-11 18:27:57,708 WARN [org.jboss.as.ee] (MSC service thread 1-7) WFLYEE0007: Not installing optional component com.comp.support.viewer.LegacyJobExecute due to an exception (enable DEBUG log level to see the cause) 2023-12-11 18:27:57,846 ERROR [org.jboss.msc.service.fail] (MSC service thread 1-4) MSC000001: Failed to start service jboss.deployment.subunit."cde-ear.ear"."cde-ejb.jar".INSTALL: org.jboss.msc.service.StartException in service jboss.deployment.subunit."cde-ear.ear"."cde-ejb.jar".INSTALL: WFLYSRV0153: Failed to process phase INSTALL of subdeployment "cde-ejb.jar" of deployment "cde-ear.ear" at org.jboss.as.server@22.0.1.Final//org.jboss.as.server.deployment.DeploymentUnitPhaseService.start(DeploymentUnitPhaseService.java:178) at org.jboss.msc@1.5.2.Final//org.jboss.msc.service.ServiceControllerImpl$StartTask.startService(ServiceControllerImpl.java:1617) at org.jboss.msc@1.5.2.Final//org.jboss.msc.service.ServiceControllerImpl$StartTask.execute(ServiceControllerImpl.java:1580) at org.jboss.msc@1.5.2.Final//org.jboss.msc.service.ServiceControllerImpl$ControllerTask.run(ServiceControllerImpl.java:1438) at org.jboss.threads@2.4.0.Final//org.jboss.threads.ContextClassLoaderSavingRunnable.run(ContextClassLoaderSavingRunnable.java:35) at org.jboss.threads@2.4.0.Final//org.jboss.threads.EnhancedQueueExecutor.safeRun(EnhancedQueueExecutor.java:1990) at org.jboss.threads@2.4.0.Final//org.jboss.threads.EnhancedQueueExecutor$ThreadBody.doRunTask(EnhancedQueueExecutor.java:1486) at org.jboss.threads@2.4.0.Final//org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1363) at java.base/java.lang.Thread.run(Thread.java:1583) Caused by: org.jboss.as.server.deployment.DeploymentUnitProcessingException: WFLYEE0024: Could not configure component FormDistSessionCommitEJB at org.jboss.as.ee@30.0.0.Final//org.jboss.as.ee.component.deployers.EEModuleConfigurationProcessor.deploy(EEModuleConfigurationProcessor.java:79) at org.jboss.as.server@22.0.1.Final//org.jboss.as.server.deployment.DeploymentUnitPhaseService.start(DeploymentUnitPhaseService.java:171) ... 8 more Caused by: org.jboss.as.server.deployment.DeploymentUnitProcessingException: WFLYEJB0384: Could not find method public abstract boolean javax.ejb.EJBObject.isIdentical(javax.ejb.EJBObject) throws java.rmi.RemoteException from view com.comp.cde.distribute.bizlogic.DistributionCommit on Jakarta Enterprise Beans class FormDistSessionCommitEJB at org.jboss.as.ejb3@30.0.0.Final//org.jboss.as.ejb3.component.session.SessionBeanObjectViewConfigurator.configure(SessionBeanObjectViewConfigurator.java:107) at org.jboss.as.ee@30.0.0.Final//org.jboss.as.ee.component.DefaultComponentViewConfigurator.configure(DefaultComponentViewConfigurator.java:92) at org.jboss.as.ee@30.0.0.Final//org.jboss.as.ee.component.deployers.EEModuleConfigurationProcessor.deploy(EEModuleConfigurationProcessor.java:65) ... 9 more
已反编译javax.ejb-api-3.2.jar中的javax.ejb.EJBObject接口,确认存在boolean isIdentical(EJBObject obj) throws RemoteException方法,但仍提示找不到该方法。
原因分析
核心问题是Jakarta EE与Java EE的命名空间冲突:
- Wildfly 30基于Jakarta EE 10构建,所有Java EE时代的API已从
javax.*迁移到jakarta.*命名空间,EJB相关接口也从javax.ejb.EJBObject变为jakarta.ejb.EJBObject。 - 应用依赖的
javax.ejb-api-3.2.jar属于Java EE体系,而Wildfly 30的EJB容器在处理视图时,默认会使用Jakarta命名空间下的接口。即使两个接口的方法签名完全一致,JVM会因为类加载器和命名空间不同,将它们视为完全不同的类,因此找不到对应的方法。 - Wildfly 10属于Java EE时代的容器,对
javax.*命名空间的EJB原生支持,而Wildfly 30的兼容性逻辑已调整,不再默认兼容旧命名空间的EJB。
解决方案
1. 迁移至Jakarta EE API(推荐长期方案)
- 替换依赖:将项目中
javax.ejb-api-3.2.jar替换为Jakarta EE对应的jakarta.ejb-api-4.0.jar(适配Jakarta EE 10)。如果使用构建工具:- Maven:
<dependency> <groupId>jakarta.ejb</groupId> <artifactId>jakarta.ejb-api</artifactId> <version>4.0.0</version> <scope>provided</scope> </dependency> - Gradle:
implementation 'jakarta.ejb:jakarta.ejb-api:4.0.0'
- Maven:
- 修改代码导入:将所有
import javax.ejb.*;替换为import jakarta.ejb.*;,确保EJB视图接口(如DistributionCommit)继承的是jakarta.ejb.EJBObject。
2. 启用Wildfly的EJB兼容性模式(临时过渡方案)
如果暂时无法大规模修改代码,可在Wildfly配置文件(standalone.xml或domain.xml)中添加兼容性配置,强制容器识别旧javax命名空间的EJB:
找到<subsystem xmlns="urn:jboss:domain:ejb3:19.0">节点,添加如下配置:
<compatibility> <jboss-ejb3> <javax-ejb-api-visibility>true</javax-ejb-api-visibility> </jboss-ejb3> </compatibility>
3. 清理类加载冲突
- 检查项目依赖,确保不同时包含
javax.ejb-api和jakarta.ejb-api,避免类加载冲突。 - 确认容器提供的API范围:将EJB API依赖的
scope设置为provided,避免打包进部署包,直接使用Wildfly容器提供的版本。
4. 验证EJB视图定义
- 检查
DistributionCommit接口是否正确继承了对应命名空间的EJBObject接口。 - 确认EJB实现类
FormDistSessionCommitEJB完整实现了视图接口的所有方法,包括继承自EJBObject的方法。
内容的提问来源于stack exchange,提问作者user989010
相关产品推荐
相关产品推荐

