Java EE7应用在Liberty 17.0.0.4启动失败(17.0.0.3可正常运行)
问题背景
我有一个Java EE 7应用,在Liberty 17.0.0.3上无论是本地运行还是在IBM Cloud上都能完美工作。但当我尝试在17.0.0.4上部署同一应用时,出现以下错误:
[1/5/18 15:50:10:366 CET] 0000001a com.ibm.ejs.csi.EJBApplicationMetaData E CNTR0190E:wfs-ejb-1.0.0-SNAPSHOT.jar模块中的APIUserManager启动单例会话Bean初始化失败,异常信息如下: javax.ejb.NoSuchEJBException:单例会话Bean wfs-ear#wfs-ejb-1.0.0-SNAPSHOT.jar#APIUserManager初始化期间发生错误,导致该单例实例被丢弃;嵌套异常为:javax.ejb.EJBException:请查看嵌套异常;嵌套异常为:javax.persistence.PersistenceException:Exception [EclipseLink-23004] (Eclipse Persistence Services - 2.6.5.WAS-v20171031-22b68cc):org.eclipse.persistence.exceptions.TransactionException 异常描述:获取Transaction Manager时出错 内部异常:java.lang.ClassNotFoundException:com.ibm.tx.jta.TransactionManagerFactory无法被com.ibm.websphere.appserver.thirdparty.eclipselink_1.0.19.201712061545找到 at com.ibm.ejs.container.util.ExceptionUtil.NoSuchEJBException(ExceptionUtil.java:497) at com.ibm.ejs.container.EJSHome.createSingletonBeanO(EJSHome.java:3754) at com.ibm.ejs.csi.EJBApplicationMetaData.createStartupBeans(EJBApplicationMetaData.java:958) at com.ibm.ejs.csi.EJBApplicationMetaData.startedModule(EJBApplicationMetaData.java:679) at com.ibm.ws.ejbcontainer.osgi.internal.EJBRuntimeImpl.start(EJBRuntimeImpl.java:970) at com.ibm.ws.ejbcontainer.osgi.internal.EJBModuleRuntimeContainerImpl.startModule(EJBModuleRuntimeContainerImpl.java:145) at com.ibm.ws.app.manager.module.internal.ModuleHandlerBase.deployModule(ModuleHandlerBase.java:99) at com.ibm.ws.app.manager.module.internal.DeployedModuleInfoImpl.installModule(DeployedModuleInfoImpl.java:49) at com.ibm.ws.app.manager.module.internal.DeployedAppInfoBase.deployModules(DeployedAppInfoBase.java:426) at com.ibm.ws.app.manager.module.internal.DeployedAppInfoBase.deployApp(DeployedAppInfoBase.java:412) at com.ibm.ws.app.manager.ear.internal.EARApplicationHandlerImpl.install(EARApplicationHandlerImpl.java:76) at com.ibm.ws.app.manager.internal.statemachine.StartAction.execute(StartAction.java:140) at com.ibm.ws.app.manager.internal.statemachine.ApplicationStateMachineImpl.enterState(ApplicationStateMachineImpl.java:1258) at com.ibm.ws.app.manager.internal.statemachine.ApplicationStateMachineImpl.performAction(ApplicationStateMachineImpl.java:1106) at com.ibm.ws.app.manager.internal.statemachine.ApplicationStateMachineImpl.run(ApplicationStateMachineImpl.java:881) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at java.lang.Thread.run(Thread.java:745) Caused by: javax.ejb.EJBException:请查看嵌套异常;嵌套异常为:javax.persistence.PersistenceException:Exception [EclipseLink-23004] (Eclipse Persistence Services - 2.6.5.WAS-v20171031-22b68cc):org.eclipse.persistence.exceptions.TransactionException 异常描述:获取Transaction Manager时出错 内部异常:java.lang.ClassNotFoundException:com.ibm.tx.jta.TransactionManagerFactory无法被com.ibm.websphere.appserver.thirdparty.eclipselink_1.0.19.201712061545找到 at com.ibm.ejs.container.util.ExceptionUtil.EJBException(ExceptionUtil.java:460) at com.ibm.ejs.container.util.ExceptionUtil.EJBException(ExceptionUtil.java:336) at com.ibm.ejs.container.BusinessExceptionMappingStrategy.mapException(BusinessExceptionMappingStrategy.java:347) at com.ibm.ejs.container.BusinessExceptionMappingStrategy.setUncheckedException(BusinessExceptionMappingStrategy.java:519) at com.ibm.ejs.container.EJSDeployedSupport.setUncheckedLocalException(EJSDeployedSupport.java:467) at com.ibm.ejs.container.SingletonBeanO.callTransactionalLifecycleInterceptors(SingletonBeanO.java:239) at com.ibm.ejs.container.SingletonBeanO.initialize(SingletonBeanO.java:329) at com.ibm.ejs.container.BeanOFactory.create(BeanOFactory.java:103) at com.ibm.ejs.container.EJSHome.createSingletonBeanO(EJSHome.java:3740) ... 16 more Caused by: javax.persistence.PersistenceException:Exception [EclipseLink-23004] (Eclipse Persistence Services - 2.6.5.WAS-v20171031-22b68cc):org.eclipse.persistence.exceptions.TransactionException 异常描述:获取Transaction Manager时出错 内部异常:java.lang.ClassNotFoundException:com.ibm.tx.jta.TransactionManagerFactory无法被com.ibm.websphere.appserver.thirdparty.eclipselink_1.0.19.201712061545找到 at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.deploy(EntityManagerSetupImpl.java:839) at org.eclipse.persistence.internal.jpa.EntityManagerFactoryDelegate.getAbstractSession(EntityManagerFactoryDelegate.java:207) at org.eclipse.persistence.internal.jpa.EntityManagerFactoryDelegate.createEntityManagerImpl(EntityManagerFactoryDelegate.java:307) at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.createEntityManagerImpl(EntityManagerFactoryImpl.java:337) at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:318) at com.ibm.ws.jpa.container.v21.internal.JPA21Runtime.createEntityManagerInstance(JPA21Runtime.java:110) at com.ibm.ws.jpa.management.JPAEMPool.getEntityManager(JPAEMPool.java:155) at com.ibm.ws.jpa.management.JPATxEntityManager.getEMInvocationInfo(JPATxEntityManager.java:254) at com.ibm.ws.jpa.management.JPATxEntityManager.getEMInvocationInfo(JPATxEntityManager.java:164) at com.ibm.ws.jpa.management.JPAEntityManager.createNamedQuery(JPAEntityManager.java:586) at com.navticon.sai.ejb.APIUserManager.reload(APIUserManager.java:83) at com.navticon.sai.ejb.APIUserManager.postConstruct(APIUserManager.java:75) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at com.ibm.ejs.container.interceptors.InterceptorProxy.invokeInterceptor(InterceptorProxy.java:205) at com.ibm.ejs.container.interceptors.InvocationContextImpl.proceed(InvocationContextImpl.java:642) at com.ibm.ws.cdi.ejb.impl.InterceptorChain.proceed(InterceptorChain.java:119) at com.ibm.ws.cdi.ejb.impl.EJBCDIInterceptorWrapper.invokeInterceptors(EJBCDIInterceptorWrapper.java:131) at com.ibm.ws.cdi.ejb.impl.EJBCDIInterceptorWrapper.postConstruct(EJBCDIInterceptorWrapper.java:67) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at com.ibm.ejs.container.interceptors.InterceptorProxy.invokeInterceptor(InterceptorProxy.java:200) at com.ibm.ejs.container.interceptors.InvocationContextImpl.proceed(InvocationContextImpl.java:631) at org.jboss.weld.ejb.AbstractEJBRequestScopeActivationInterceptor.aroundInvoke(AbstractEJBRequestScopeActivationInterceptor.java:73) at com.ibm.ws.cdi.ejb.interceptor.WeldSessionBeanInterceptorWrapper.aroundInvoke(WeldSessionBeanInterceptorWrapper.java:58) at com.ibm.ws.cdi.ejb.interceptor.WeldSessionBeanInterceptorWrapper.postConstruct(WeldSessionBeanInterceptorWrapper.java:67) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at com.ibm.ejs.container.interceptors.InterceptorProxy.invokeInterceptor(InterceptorProxy.java:200) at com.ibm.ejs.container.interceptors.InvocationContextImpl.proceed(InvocationContextImpl.java:631) at com.ibm.ejs.container.interceptors.InvocationContextImpl.doLifeCycle(InvocationContextImpl.java:335) at com.ibm.ejs.container.SingletonBeanO.callTransactionalLifecycleInterceptors(SingletonBeanO.java:236) ... 19 more Caused by: Exception [EclipseLink-23004] (Eclipse Persistence Services - 2.6.5.WAS-v20171031-22b68cc):org.eclipse.persistence.exceptions.TransactionException 异常描述:获取Transaction Manager时出错 内部异常:java.lang.ClassNotFoundException:com.ibm.tx.jta.TransactionManagerFactory无法被com.ibm.websphere.appserver.thirdparty.eclipselink_1.0.19.201712061545找到 at org.eclipse.persistence.exceptions.TransactionException.errorObtainingTransactionManager(TransactionException.java:125) at org.eclipse.persistence.transaction.JTATransactionController.<init>(JTATransactionController.java:69) at org.eclipse.persistence.transaction.was.WebSphereTransactionController.<init>(WebSphereTransactionController.java:46) at org.eclipse.persistence.transaction.was.WebSphereLibertyTransactionController.<init>(WebSphereLibertyTransactionController.java:17) at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.lang.reflect.Constructor.newInstance(Constructor.java:423) at java.lang.Class.newInstance(Class.java:442) at org.eclipse.persistence.internal.security.PrivilegedAccessHelper.newInstanceFromClass(PrivilegedAccessHelper.java:517) at org.eclipse.persistence.platform.server.ServerPlatformBase.initializeExternalTransactionController(ServerPlatformBase.java:309) at org.eclipse.persistence.internal.sessions.DatabaseSessionImpl.preConnectDatasource(DatabaseSessionImpl.java:805) at org.eclipse.persistence.internal.sessions.DatabaseSessionImpl.loginAndDetectDatasource(DatabaseSessionImpl.java:763) at org.eclipse.persistence.internal.jpa.EntityManagerFactoryProvider.login(EntityManagerFactoryProvider.java:253) at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.deploy(EntityManagerSetupImpl.java:755) ... 56 more Caused by: java.lang.ClassNotFoundException:com.ibm.tx.jta.TransactionManagerFactory无法被com.ibm.websphere.appserver.thirdparty.eclipselink_1.0.19.201712061545找到 at org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:484) at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:395) at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:387) at org.eclipse.osgi.internal.loader.ModuleClassLoader.loadClass(ModuleClassLoader.java:150) at java.lang.ClassLoader.loadClass(ClassLoader.java:357) at java.lang.Class.forName0(Native Method) at java.lang.Class.forName(Class.java:264) at org.eclipse.persistence.internal.security.PrivilegedAccessHelper.getClassForName(PrivilegedAccessHelper.java:151) at org.eclipse.persistence.transaction.was.WebSphereTransactionController.acquireTransactionManager(WebSphereTransactionController.java:84) at org.eclipse.persistence.transaction.JTATransactionController.<init>(JTATransactionController.java:67) ... 69 more
解决建议
从错误栈可以看出,核心问题是EclipseLink的类加载器无法找到Liberty的事务管理器工厂类com.ibm.tx.jta.TransactionManagerFactory,这通常是版本升级后特性配置或类加载冲突导致的,试试以下几个方案:
1. 确保Liberty服务器特性配置正确
Liberty 17.0.0.4可能调整了EclipseLink的集成方式,检查你的server.xml,确保包含必要的JPA、事务和EclipseLink特性:
<featureManager> <!-- 推荐使用完整的Java EE 7特性集,或者拆分指定所需特性 --> <feature>javaee-7.0</feature> <!-- 显式启用EclipseLink特性,避免自动检测问题 --> <feature>eclipselink-2.6</feature> </featureManager>
如果之前依赖默认特性,升级后显式声明eclipselink特性能确保Liberty加载正确的EclipseLink模块。
2. 显式配置EclipseLink的事务控制器
在persistence.xml中指定目标服务器和事务控制器类,强制EclipseLink使用Liberty兼容的事务管理实现:
<persistence-unit name="你的持久化单元名称" transaction-type="JTA"> <!-- 其他配置(数据源、实体类等) --> <properties> <!-- 指定目标服务器为WebSphere Liberty --> <property name="eclipselink.target-server" value="WebSphere_Liberty"/> <!-- 显式指定事务控制器类 --> <property name="eclipselink.transaction.controller" value="org.eclipse.persistence.transaction.was.WebSphereLibertyTransactionController"/> </properties> </persistence-unit>
这会绕过EclipseLink的自动检测逻辑,直接使用正确的事务控制器,避免类加载路径问题。
3. 移除应用打包中的EclipseLink依赖
如果你的应用WAR/EAR中包含了eclipselink.jar,会和Liberty容器提供的EclipseLink模块产生类加载冲突。修改你的构建配置,将EclipseLink依赖设置为provided范围:
<dependency> <groupId>org.eclipse.persistence</groupId> <artifactId>eclipselink</artifactId> <version>2.6.5</version> <scope>provided</scope> </dependency>
这样应用会使用Liberty自带的EclipseLink版本,确保类加载一致性。
4. 验证事务特性的启用
确保server.xml中启用了事务管理特性,虽然javaee-7.0已经包含,但如果是拆分特性配置的话,需要单独添加:
<feature>transaction-1.2</feature>
这个特性是JTA事务管理的基础,缺少它会导致事务管理器类无法被加载。
5. 检查EclipseLink特性版本兼容性
Liberty 17.0.0.4中的eclipselink特性可能对应不同的版本,你可以查看logs/featureManager.log确认加载的版本。如果版本不兼容,尝试在server.xml中指定具体版本:
<feature>eclipselink-2.6.5</feature>
匹配你应用依赖的EclipseLink版本,避免版本差异导致的类加载问题。
内容的提问来源于stack exchange,提问作者danishrulez

