Search code examples
javaclassloaderjboss6.xopenjpa

ClassCastException with OpenJPA in Jboss 6.0


Jboss 6 comes with JPA 2.0 (hibernate-jpa-2.0-api.jar) and Hibernate 3.6.6 as the implementation.

I have a web application that has OpenJPA 2.0 library (openjpa-all-2.1.0.jar). I have set the classloader isolation in the jboss-web.xml as shown below

<class-loading java2ClassLoadingCompliance="false">
    <loader-repository>
        some.example:loader=some-webapp.war
        <loader-repository-config>java2ParentDelegation=false</loader-repository-config>
    </loader-repository>
</class-loading>

When I deploy the application I get this error

ERROR [AbstractKernelController] Error installing to Start: name=persistence.unit:unitName=some.war#some state=Create: java.lang.ClassCastException: org.apache.openjpa.persistence.PersistenceProviderImpl cannot be cast to javax.persistence.spi.PersistenceProvider

This is strange since, org.apache.openjpa.persistence.PersistenceProviderImpl already implements javax.persistence.spi.PersistenceProvider

I did a -version:class to check where the javax.persistence.spi.PersistenceProvider is being loaded from and it appears that it's being loaded from the web application first and then from jboss6\common\lib

[Loaded javax.persistence.spi.PersistenceProviderResolverHolder$1 from vfs:/home/sathwik/apps/jboss-6.1.0.Final/server/default/deploy/some-webapp.war/WEB-INF/lib/openjpa-all-2.1.0.jar/]

[Loaded javax.persistence.spi.PersistenceProvider from vfs:/home/sathwik/apps/jboss-6.1.0.Final/common/lib/hibernate-jpa-2.0-api.jar/]

From the Manifest.mf file i was able to gather the JDK version used to compile hibernate-jpa-2.0-api.jar is compiled with Build-Jdk: 1.5.0_19, openjpa-all-2.1.0 is compiled with Build-Jdk: 1.6.0_22

Can anyone help me out in understanding why this exception?


Solution

  • According to the OpenJPA Dependencies page, the openjpa-all JAR file

    [...] includes the OpenJPA core code plus all of the runtime dependencies for Java SE environments

    You're not running in a JavaSE envrionment, you're in a full-blown JavaEE environment, which already has many of the ancillary API classes contained within the openjpa-all JAR. As a result, you're getting conflicts caused by loading classes of the same name, but from different classloaders.

    You should replace openjpa-all with more specific JAR files (i.e. openjpa-2.1.0.jar and whatever others are necessary to make it work - see the above page).