Hibernate JPA 在从 JBoss 7 迁移到 WildFly 8 时出现 ClassCastException。

huangapple go评论81阅读模式
英文:

Hibernate JPA ClassCastException when moving application from JBoss 7 to WildFly 8

问题

我有一个相对复杂的软件部分,目前正在Java 7和JBoss 7.1.2下运行。作为将其升级到最新版本的第一步,我正在尝试将其升级到Java 8和WildFly 8.2.1下运行。

我已经设法使大多数功能正常运行,但在Hibernate/JPA版本方面遇到了问题。我的应用程序打包为一个EAR文件,其中包括两个WAR文件和一些JAR文件。其中一个WAR文件使用Hibernate 4.3.x和JPA 2.1,似乎正常工作,但另一个WAR文件(主要是第三方代码)使用Hibernate 3.6.x和JPA 2.0。

不知何故,有人成功地让它在JBoss 7.1.x下工作,但我无法在WildFly 8.2.x下重现这个奇迹,并且不断遇到以下异常:

org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.springframework.webflow.execution.FlowExecutionException: Exception thrown in state 'ipaidLoginForm' of flow 'login'
[...]
Caused by: java.lang.ClassCastException: org.hibernate.jpa.HibernatePersistenceProvider cannot be cast to javax.persistence.spi.PersistenceProvider
	at javax.persistence.Persistence$1.isLoaded(Persistence.java:92)
	at org.hibernate.validator.internal.engine.resolver.JPATraversableResolver.isReachable(JPATraversableResolver.java:56)
	at org.hibernate.validator.internal.engine.resolver.DefaultTraversableResolver.isReachable(DefaultTraversableResolver.java:137)
	at org.hibernate.validator.internal.engine.resolver.CachingTraversableResolverForSingleValidation.isReachable(CachingTraversableResolverForSingleValidation.java:46)
	at org.hibernate.validator.internal.engine.ValidatorImpl.isReachable(ValidatorImpl.java:1396)
	... 75 more

我已经尝试了我能想到的各种组合,包括包含/排除Hibernate和JPA的不同版本。我认为解决方案应该是排除WildFly内置的Hibernate和JPA,而是使用打包在我的两个WAR文件中的两个版本。

我的jboss-deployment-structure.xml文件如下所示:

<jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.0">
	<ear-subdeployments-isolated>false</ear-subdeployments-isolated>
	<deployment>
		<exclusions>
			<module name="org.hibernate" />
			<module name="javax.persistence.api" />
			<module name="org.jboss.resteasy.resteasy-jackson-provider" />
		</exclusions>
		<dependencies>
			<module name="javax.servlet.jstl.api" export="true" />
			<module name="org.jboss.resteasy.resteasy-jackson2-provider" services="import" />
            <module name="com.fasterxml.jackson.jaxrs.jackson-jaxrs-json-provider" />
		</dependencies>
	</deployment>
</jboss-deployment-structure>

未工作的WAR文件具有以下persistence.xml

<persistence xmlns="http://java.sun.com/xml/ns/persistence"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
        version="2.0">

	<persistence-unit name="CasPersistence" transaction-type="RESOURCE_LOCAL">
		<provider>org.hibernate.ejb.HibernatePersistence</provider>
		<class>org.jasig.cas.services.AbstractRegisteredService</class>
		<class>org.jasig.cas.services.RegexRegisteredService</class>
		<class>org.jasig.cas.services.RegisteredServiceImpl</class>
		<class>org.jasig.cas.ticket.TicketGrantingTicketImpl</class>
		<class>org.jasig.cas.ticket.ServiceTicketImpl</class>
		<class>org.jasig.cas.ticket.registry.support.JpaLockingStrategy$Lock</class>
		<!-- DriveSync specific change - Add proper for hibernate cache -->
		<properties>
			<property name="hibernate.cache.region.factory_class" value="net.sf.ehcache.hibernate.EhCacheRegionFactory"/>
		</properties>
	</persistence-unit>
</persistence>

一些原因,工作的WAR文件似乎根本没有persistence.xml?我不确定这是否正常?

任何建议,甚至只是指出正确的方向,都将不胜感激!

英文:

I have a somewhat crufty piece of software that is currently running under Java 7 and JBoss 7.1.2. As a first step to bringing this up to current times, I'm trying to bump this up to running under Java 8 and WildFly 8.2.1.

I've managed to get most things working, but am running into an issue with Hibernate / JPA versions. My application is packaged as an EAR file with two WAR files, along with a few JAR files. One of the WAR files is using Hibernate 4.3.x and JPA 2.1 and appears to be working ok, but the other WAR file (mostly 3rd party code) is using Hibernate 3.6.x and JPA 2.0.

Somehow someone managed to magically make that all work under JBoss 7.1.x, but I've bene unable to repeat that magic under WildFly 8.2.x and keep getting exceptions such as the following:

org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.springframework.webflow.execution.FlowExecutionException: Exception thrown in state &#39;ipaidLoginForm&#39; of flow &#39;login&#39;
[...]
Caused by: java.lang.ClassCastException: org.hibernate.jpa.HibernatePersistenceProvider cannot be cast to javax.persistence.spi.PersistenceProvider
	at javax.persistence.Persistence$1.isLoaded(Persistence.java:92)
	at org.hibernate.validator.internal.engine.resolver.JPATraversableResolver.isReachable(JPATraversableResolver.java:56)
	at org.hibernate.validator.internal.engine.resolver.DefaultTraversableResolver.isReachable(DefaultTraversableResolver.java:137)
	at org.hibernate.validator.internal.engine.resolver.CachingTraversableResolverForSingleValidation.isReachable(CachingTraversableResolverForSingleValidation.java:46)
	at org.hibernate.validator.internal.engine.ValidatorImpl.isReachable(ValidatorImpl.java:1396)
	... 75 more

I have been trying just about every combination I can think of to include / exclude versions of Hibernate and JPA. I believe the solution should be the exclude the WildFly built-in Hibernate and JPA and use the two versions that are bundled in my two WARs.

My jboss-deployment-structure.xml file looks like this:

&lt;jboss-deployment-structure xmlns=&quot;urn:jboss:deployment-structure:1.0&quot;&gt;
	&lt;ear-subdeployments-isolated&gt;false&lt;/ear-subdeployments-isolated&gt;
	&lt;deployment&gt;
		&lt;exclusions&gt;
			&lt;module name=&quot;org.hibernate&quot; /&gt;
			&lt;module name=&quot;javax.persistence.api&quot; /&gt;
			&lt;module name=&quot;org.jboss.resteasy.resteasy-jackson-provider&quot; /&gt;
		&lt;/exclusions&gt;
		&lt;dependencies&gt;
			&lt;module name=&quot;javax.servlet.jstl.api&quot; export=&quot;true&quot; /&gt;
			&lt;module name=&quot;org.jboss.resteasy.resteasy-jackson2-provider&quot; services=&quot;import&quot; /&gt;
            &lt;module name=&quot;com.fasterxml.jackson.jaxrs.jackson-jaxrs-json-provider&quot; /&gt;
		&lt;/dependencies&gt;
	&lt;/deployment&gt;
&lt;/jboss-deployment-structure&gt;

The WAR file that is not working has the following persistence.xml:

&lt;persistence xmlns=&quot;http://java.sun.com/xml/ns/persistence&quot;
        xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
        xsi:schemaLocation=&quot;http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd&quot;
        version=&quot;2.0&quot;&gt;

	&lt;persistence-unit name=&quot;CasPersistence&quot; transaction-type=&quot;RESOURCE_LOCAL&quot;&gt;
		&lt;provider&gt;org.hibernate.ejb.HibernatePersistence&lt;/provider&gt;
		&lt;class&gt;org.jasig.cas.services.AbstractRegisteredService&lt;/class&gt;
		&lt;class&gt;org.jasig.cas.services.RegexRegisteredService&lt;/class&gt;
		&lt;class&gt;org.jasig.cas.services.RegisteredServiceImpl&lt;/class&gt;
		&lt;class&gt;org.jasig.cas.ticket.TicketGrantingTicketImpl&lt;/class&gt;
		&lt;class&gt;org.jasig.cas.ticket.ServiceTicketImpl&lt;/class&gt;
		&lt;class&gt;org.jasig.cas.ticket.registry.support.JpaLockingStrategy$Lock&lt;/class&gt;
		&lt;!-- DriveSync specific change - Add proper for hibernate cache --&gt;
		&lt;properties&gt;
			&lt;property name=&quot;hibernate.cache.region.factory_class&quot; value=&quot;net.sf.ehcache.hibernate.EhCacheRegionFactory&quot;/&gt;
		&lt;/properties&gt;
	&lt;/persistence-unit&gt;
&lt;/persistence&gt;

Somehow, the WAR file that is working doesn't seem to have a persistence.xml at all? I'm not sure if that is normal?

Any suggestions, even just pointing in the right direction, would be hugely appreciated!

答案1

得分: 1

问题可能是您没有隔离子部署,因此出现了2个Hibernate和JPA版本冲突。 https://www.mastertheboss.com/jbossas/jboss-as-7/jboss-as-7-classloading/ 可能对您有所帮助。

英文:

I think the issue is that you haven't isolated your subdeployments thus you are getting the 2 hibernate and jpa versions to collide. https://www.mastertheboss.com/jbossas/jboss-as-7/jboss-as-7-classloading/ might help in your case

答案2

得分: 0

对于那个特定版本对升级来说,我不太熟悉,但是从一个 JBoss 容器升级到另一个版本通常不会像在新版本中放置你的 EAR 文件然后启动那样简单。

最有可能的情况是,你需要进行大量的重写和重新配置依赖项,因为在不同版本之间的类加载器架构发生了重大变化。

这也将为你提供一个机会(甚至是强制性的机会)来升级你的 Spring 和 Hibernate 版本,将它们升级到相同的版本号。

这些升级可能最终需要更多的重写。例如,当我参与类似项目(不同的 JBoss 版本)时,我们最终不得不重写整个应用程序的事务处理机制,重新架构各个 WAR 文件和 EJB JAR 文件(更改哪些类放在哪里),等等。

英文:

Not familiar with that specific pair of versions, but upgrading from one JBoss container to another version is rarely as simple as dropping your ear in the new version and starting it up.

Most likely you're going to have to do a LOT of rewriting and rewiring of dependencies, as there have been big changes in the classloader architecture between versions.

Which will also give you a chance (mandated even) to upgrade your Spring and Hibernate versions and bringing them all to the same version numbers.

Which upgrades may end up requiring more rewriting. E.g. when I was involved in a similar project (different JBoss versions) we ended up having to rewrite the entire transaction handling mechanism of the application, rearchitecture the various wars and ejb jars (changing which classes went where), etc. etc..

huangapple
  • 本文由 发表于 2023年5月25日 11:37:09
  • 转载请务必保留本文链接:https://go.coder-hub.com/76328766.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定