WebLogic14.1.1.0中避免加载EclipseLink PersistenceProvider求助
问题描述
在MO层使用@Valid注解校验输入数据,Tomcat服务器运行正常,但部署到WebLogic时抛出类转换异常:
Caused by: java.lang.ClassCastException: class org.eclipse.persistence.jpa.PersistenceProvider cannot be cast to class javax.persistence.spi.PersistenceProvider (org.eclipse.persistence.jpa.PersistenceProvider is in unnamed module of loader com.oracle.classloader.weblogic.LaunchClassLoader @3e92efc3; javax.persistence.spi.PersistenceProvider is in unnamed module of loader weblogic.utils.classloaders.ChangeAwareClassLoader @8ae852)
已在persistence.xml中指定<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>,但问题仍未解决,需要避免加载WebLogic容器自带的EclipseLink持久化单元。
相关版本:Hibernate JPA hibernate-jpa-2.1-api-1.0.0.Final.jar;Hibernate Validator hibernate-validator-5.4.0.Final.jar
核心原因
WebLogic容器默认自带EclipseLink作为JPA实现,且容器类加载器优先级高于应用类加载器。导致javax.persistence.spi.PersistenceProvider接口由容器加载,而应用中的Hibernate实现类由应用类加载器加载,不同类加载器加载的类无法互相转换,从而触发异常。
解决步骤
1. 配置WebLogic优先加载应用类
在WEB-INF目录下新建或修改weblogic.xml,添加类加载优先级配置,强制WebLogic优先从应用的WEB-INF/lib中加载指定包的类:
<weblogic-web-app xmlns="http://xmlns.oracle.com/weblogic/weblogic-web-app" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.oracle.com/weblogic/weblogic-web-app http://xmlns.oracle.com/weblogic/weblogic-web-app/1.7/weblogic-web-app.xsd"> <container-descriptor> <prefer-application-packages> <package-name>javax.persistence.*</package-name> <package-name>org.hibernate.*</package-name> <package-name>org.hibernate.jpa.*</package-name> <package-name>javax.validation.*</package-name> <package-name>org.hibernate.validator.*</package-name> </prefer-application-packages> </container-descriptor> </weblogic-web-app>
2. 确认persistence.xml配置正确性
确保META-INF/persistence.xml中明确指定Hibernate作为持久化提供者,配置示例:
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd" version="2.1"> <persistence-unit name="yourPersistenceUnit" transaction-type="RESOURCE_LOCAL"> <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider> <!-- 注册实体类 --> <class>com.yourcompany.entity.YourEntity</class> <properties> <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/> <!-- 其他Hibernate配置属性 --> </properties> </persistence-unit> </persistence>
3. 清理项目依赖,排除EclipseLink
检查项目依赖管理文件(如Maven的pom.xml),确保没有引入EclipseLink依赖,同时保证Hibernate相关依赖唯一:
<dependencies> <!-- Hibernate JPA API --> <dependency> <groupId>org.hibernate.javax.persistence</groupId> <artifactId>hibernate-jpa-2.1-api</artifactId> <version>1.0.0.Final</version> </dependency> <!-- Hibernate Core --> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>5.4.0.Final</version> <!-- 与Validator版本保持兼容 --> </dependency> <!-- Hibernate Validator --> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-validator</artifactId> <version>5.4.0.Final</version> </dependency> <!-- 排除第三方依赖中的EclipseLink --> <dependency> <groupId>your.dependency.group</groupId> <artifactId>your.dependency.artifact</artifactId> <exclusions> <exclusion> <groupId>org.eclipse.persistence</groupId> <artifactId>eclipselink</artifactId> </exclusion> </exclusions> </dependency> </dependencies>
4. 检查WebLogic控制台JPA配置
登录WebLogic控制台,进入域结构 -> 服务器 -> 目标服务器 -> 配置 -> 常规,确认没有强制指定EclipseLink为默认JPA提供者,若有则修改为Hibernate,或保持默认但通过应用配置覆盖。
内容的提问来源于stack exchange,提问作者Jitendra Yadav

