OpenLiberty启动时类转换抛出StackOverflowError问题求助
OpenLiberty 23.0.0.12启动时抛出StackOverflowError,使用的Hibernate版本为6.4.2.Final。
错误详情
E CWWJP0055E: An error occurred while attempting to transform the org.hibernate.jpa.internal.enhance.EnhancingClassTransformerImpl$Entry Java Class. The following failure detail was gathered: ---------- Exception thrown by transformer: java.lang.StackOverflowError at java.base/java.io.InputStream.<init>(InputStream.java:61) at com.ibm.ws.artifact.zip.internal.ZipFileEntry$1.<init>(ZipFileEntry.java:199) at com.ibm.ws.artifact.zip.internal.ZipFileEntry.getInputStream(ZipFileEntry.java:199) at com.ibm.ws.artifact.overlay.internal.DirectoryBasedOverlayContainerImpl$OverlayDelegatingEntry.getInputStream(DirectoryBasedOverlayContainerImpl.java:488) at com.ibm.ws.adaptable.module.internal.AdaptableEntryImpl.adapt(AdaptableEntryImpl.java:104) at com.ibm.ws.adaptable.module.internal.InterpretedEntryImpl.adapt(InterpretedEntryImpl.java:68) at com.ibm.ws.classloading.internal.ContainerClassLoader$EntryUniversalResource.getActualBytes(ContainerClassLoader.java:373) at com.ibm.ws.classloading.internal.ContainerClassLoader$EntryUniversalResource.getByteResourceInformation(ContainerClassLoader.java:365) at com.ibm.ws.classloading.internal.ContainerClassLoader$SmartClassPathImpl.getByteResourceInformation(ContainerClassLoader.java:1226) at com.ibm.ws.classloading.internal.ContainerClassLoader.findClassBytes(ContainerClassLoader.java:1628) at com.ibm.ws.classloading.internal.AppClassLoader.findClassBytes(AppClassLoader.java:540) at com.ibm.ws.classloading.internal.AppClassLoader.findClass(AppClassLoader.java:324) at com.ibm.ws.classloading.internal.AppClassLoader.findOrDelegateLoadClass(AppClassLoader.java:714) at com.ibm.ws.classloading.internal.AppClassLoader.loadClass(AppClassLoader.java:586) at com.ibm.ws.classloading.internal.AppClassLoader.loadClass(AppClassLoader.java:553) at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:525) at org.hibernate.jpa.internal.enhance.EnhancingClassTransformerImpl.getEnhancer(EnhancingClassTransformerImpl.java:71) at org.hibernate.jpa.internal.enhance.EnhancingClassTransformerImpl.transform(EnhancingClassTransformerImpl.java:49) at com.ibm.ws.jpa.management.JPAPUnitInfo.transformClass(JPAPUnitInfo.java:1263) at com.ibm.ws.classloading.internal.ClassLoadingServiceImpl$ClassFileTransformerAdapter.transform(ClassLoadingServiceImpl.java:390) at com.ibm.ws.classloading.internal.AppClassLoader.doTransformation(AppClassLoader.java:382) at com.ibm.ws.classloading.internal.AppClassLoader.transformClassBytes(AppClassLoader.java:375) at com.ibm.ws.classloading.internal.AppClassLoader.transformClassBytes(AppClassLoader.java:360) at com.ibm.ws.classloading.internal.AppClassLoader.findClass(AppClassLoader.java:331) at com.ibm.ws.classloading.internal.AppClassLoader.findOrDelegateLoadClass(AppClassLoader.java:714) at com.ibm.ws.classloading.internal.AppClassLoader.loadClass(AppClassLoader.java:586) at com.ibm.ws.classloading.internal.AppClassLoader.loadClass(AppClassLoader.java:553) ... at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:525) at org.hibernate.jpa.internal.enhance.EnhancingClassTransformerImpl.getEnhancer(EnhancingClassTransformerImpl.java:71) at org.hibernate.jpa.internal.enhance.EnhancingClassTransformerImpl.transform(EnhancingClassTransformerImpl.java:49) at com.ibm.ws.jpa.management.JPAPUnitInfo.transformClass(JPAPUnitInfo.java:1263) at com.ibm.ws.classloading.internal.ClassLoadingServiceImpl$ClassFileTransformerAdapter.transform(ClassLoadingServiceImpl.java:390) at com.ibm.ws.classloading.internal.AppClassLoader.doTransformation(AppClassLoader.java:382) at com.ibm.ws.classloading.internal.AppClassLoader.transformClassBytes(AppClassLoader.java:375) at com.ibm.ws.classloading.internal.AppClassLoader.transformClassBytes(AppClassLoader.java:360) at com.ibm.ws.classloading.internal.AppClassLoader.findClass(AppClassLoader.java:331) at com.ibm.ws.classloading.internal.AppClassLoader.findOrDelegateLoadClass(AppClassLoader.java:714) at com.ibm.ws.classloading.internal.AppClassLoader.loadClass(AppClassLoader.java:586) at com.ibm.ws.classloading.internal.AppClassLoader.loadClass(AppClassLoader.java:553) at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:525)
持久化单元配置
<persistence xmlns="https://jakarta.ee/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://jakarta.ee/xml/ns/persistence https://jakarta.ee/xml/ns/persistence/persistence_3_0.xsd" version="3.0"> <persistence-unit name="MY_DB" transaction-type="JTA"> <description>MY Database</description> <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider> <jta-data-source>jdbc/APP/APP_db_hsql</jta-data-source> <properties> <property name="hibernate.show_sql" value="false" /> <property name="hibernate.format_sql" value="true" /> <property name="hibernate.default_schema" value="PUBLIC" /> <property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect" /> <property name="hibernate.jdbc.batch_size" value="10000" /> <property name="hibernate.order_inserts" value="true" /> <property name="hibernate.order_updates" value="true" /> <property name="hibernate.transaction.jta.platform" value="org.hibernate.engine.transaction.jta.platform.internal.WebSphereLibertyJtaPlatform" /> <property name="hibernate.bytecode.use_reflection_optimizer" value="false"/> </properties> </persistence-unit> </persistence>
类加载器配置
<library apiTypeVisibility="spec,ibm-api,api,stable,third-party" id="libs"> <fileset dir="${appl_path}/appl_libs" includes="*.jar"/> </library> <classloader apiTypeVisibility="spec,ibm-api,api,stable,third-party" commonLibraryRef="libs" />
libs目录包含:hsqldb-2.4.1.jar、dom4j-1.6.1.jar、jandex-3.1.6.jar
OpenLiberty特性配置
<featureManager> <feature>localConnector-1.0</feature> <feature>appSecurity-5.0</feature> <feature>beanValidation-3.0</feature> <feature>cdi-4.0</feature> <feature>enterpriseBeansLite-4.0</feature> <feature>mail-2.1</feature> <feature>restfulWS-3.1</feature> <feature>jdbc-4.2</feature> <feature>jndi-1.0</feature> <feature>persistenceContainer-3.1</feature> <feature>faces-4.0</feature> <feature>pages-3.1</feature> <feature>localConnector-1.0</feature> <feature>servlet-6.0</feature> <feature>enterpriseBeansPersistentTimer-4.0</feature> <feature>xmlBinding-4.0</feature> <feature>xmlWS-4.0</feature> <feature>messagingClient-3.0</feature> <feature>ldapRegistry-3.0</feature> <feature>transportSecurity-1.0</feature> <feature>connectors-2.1</feature> </featureManager>
已尝试的操作:
- 降级Hibernate或升级OpenLiberty版本,问题未解决
- 设置类加载器
delegation="parentLast"后,StackOverflowError消失,但persistenceManager无法启动
1. 彻底禁用Hibernate字节码增强
错误根源是Hibernate类转换器触发循环加载,现有配置hibernate.bytecode.use_reflection_optimizer=false不足以完全关闭增强,需添加:
在persistence.xml的properties节点中加入:
<property name="hibernate.bytecode.enhancer.enable" value="false"/>
该配置会彻底关闭Hibernate字节码增强机制,避免类转换器被触发,打破循环加载死循环。
2. 调整类加载器过滤规则
修改类加载器配置,将Hibernate类单独隔离,避免被OpenLiberty的JPA容器转换:
<library id="hibernateLibs"> <fileset dir="${appl_path}/hibernate_libs" includes="*.jar"/> </library> <classloader commonLibraryRef="libs,hibernateLibs" delegation="parentFirst"> <filter delegation="parentLast" pattern="org.hibernate.**"/> </classloader>
此配置让Hibernate类优先从应用库加载,同时阻止OpenLiberty的JPA容器对Hibernate内部类进行转换,避免循环触发。
3. 替换OpenLiberty JPA特性
当前使用的persistenceContainer-3.1会自带容器JPA实现,与Hibernate冲突,替换为通用JPA特性:
在featureManager中修改:
<feature>jpa-3.1</feature> <!-- 删除 persistenceContainer-3.1 -->
确保persistence.xml中provider节点明确指定Hibernate,避免容器自动选择自带实现。
4. 校验Hibernate依赖完整性
确认Hibernate 6.4.2.Final的所有依赖包版本兼容,特别是字节码增强相关的bytebuddy、hibernate-enhance等组件,避免因依赖缺失或版本不匹配导致类加载异常。
内容的提问来源于stack exchange,提问作者jewen

