Search code examples
jpajbossclasspathclassloader

Using JPA 2.1 in EAP 6.4.0


I searched for a solution for this problem without having success so far.

We're migrating our aplications over to EAP 6.4.0, and our applications relies on JPA 2.1. However, JBoss is a Java EE 6 server, and therefore includes JPA 2.0 in the form of a module.

I tried including the JPA API jar directly in my WEB-INF/lib directory, thinking the classloader would prefer this one over the one from the system.

I have tried to include a jboss-deployment-structure.xml file in my ear. I tried it under ear/META-INF, ear/war/META-INF, and ear/war/WEB-INF.

In the jboss-deployment-structure.xml file, I tried to: exclude the javax.persistence.api module create my own module with JPA 2.1 and add a dependency to it exclude the jpa subsystem

I also tried to set the export attribute to false in the javax.persistence.api module.xml file located under jboss-eap-6.4.0\modules\system\layers\base\javax\persistence\api\main

I tried removing the jpa subsystem from the standalone.xml.

All of these things resulted in the JPA 2.0 jar being used.

The only way I got it to work was to replace the actual jar in the module directory (jboss-eap-6.4.0\modules\system\layers\base\javax\persistence\api\main). But that's not a valid solution as other apps or services in the server may actually need the old version of the API.

Is there a way to do this correctly (without migrating to another server nor changing the code)?


Solution

  • Please take a look at: https://issues.jboss.org/browse/WFCORE-209

    This is a copy from the link above:

    workaround 1

    update the javaee/api/main.module.xml as followed:

    <!--<module name="javax.persistence.api" export="true"/>-->
    

    though this is non-portable.

    workaround 2

    update jboss-deployment-structure.xml as followed:

    <?xml version="1.0" encoding="UTF-8"?>
    <jboss-deployment-structure>
        <deployment>
            <exclude-subsystems>
                <subsystem name="jpa" />
            </exclude-subsystems>
            <exclusions>
                <!-- WFCORE-209 workaround -->
                <module name="javaee.api" />
                <!-- --------------------- -->
                <module name="javax.persistence.api" />
                <module name="org.hibernate" />
            </exclusions>
            <dependencies>
                <!-- WFCORE-209 workaround -->
                <module name="javax.activation.api" export="true"/>
                <module name="javax.annotation.api" export="true"/>
                <module name="javax.ejb.api" export="true"/>
                <module name="javax.el.api" export="true"/>
                <module name="javax.enterprise.api" export="true"/>
                <module name="javax.enterprise.deploy.api" export="true"/>
                <module name="javax.inject.api" export="true"/>
                <module name="javax.interceptor.api" export="true"/>
                <module name="javax.jms.api" export="true"/>
                <module name="javax.jws.api" export="true"/>
                <module name="javax.mail.api" export="true"/>
                <module name="javax.management.j2ee.api" export="true"/>
                <!-- <module name="javax.persistence.api" export="true"/> -->
                <module name="javax.resource.api" export="true"/>
                <module name="javax.rmi.api" export="true"/>
                <module name="javax.security.auth.message.api" export="true"/>
                <module name="javax.security.jacc.api" export="true"/>
                <module name="javax.servlet.api" export="true"/>
                <module name="javax.servlet.jsp.api" export="true"/>
                <module name="javax.transaction.api" export="true"/>
                <module name="javax.validation.api" export="true"/>
                <module name="javax.ws.rs.api" export="true"  services="export"/>
                <module name="javax.xml.bind.api" export="true"/>
                <module name="javax.xml.registry.api" export="true"/>
                <module name="javax.xml.soap.api" export="true"/>
                <module name="javax.xml.ws.api" export="true"/>
    
                <!-- This one always goes last. -->
                <module name="javax.api" export="true"/>
                <!-- --------------------- -->
            </dependencies>
        </deployment>
    </jboss-deployment-structure>
    

    this is fully portable