2 Replies Latest reply on Mar 17, 2016 2:46 PM by lindholm

    Including JPA jar in Archive for Hibernate to find

    lindholm

      How can I make Hibernate use a JPA jar using Arquillian?

       

      Looking at the debug information I see Hibernate apparently using the class folder from where the persistence.xml comes

      from (which is strange since the file lives in the ShrinkWrap archive???).

       

      At the moment I'm created an ugly hack where I explode the jar file into the

      test-classes folder just so Hibernate will find the JPA entities.

       

      Thanks

       

          George

        • 1. Re: Including JPA jar in Archive for Hibernate to find
          mjobanek

          Hi,

          could you provide your @Deployment method please?

          Thanks

          Matous

          • 2. Re: Including JPA jar in Archive for Hibernate to find
            lindholm

            Here is how I build the Archive:

            @Transactional(TransactionMode.ROLLBACK)

            @RunWith(Arquillian.class)

            public class ArquillianDerbyTest {

                private final static Logger logger = LoggerFactory.getLogger(ArquillianDerbyTest.class);

             

             

                public static final String derbyResource = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" //

                        + "<Resources>\n" //

                        + "    <Resource id=\"jboss/datasource/ubcRegiDomainDS\" type=\"DataSource\">\n" //

                        + "        JdbcDriver      org.apache.derby.jdbc.EmbeddedDriver\n" //

                        + "        JdbcUrl         jdbc:derby:memory:testDB;create=true\n" //

                        + "        JtaManaged      true\n" //

                        + "        logAbandoned    true\n" //

                        + "    </Resource>\n" //

                        + "</Resources>\n";

             

             

                public static final String oracleResource = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" //

                        + "<Resources>\n" //

                        + "    <Resource id=\"jboss/datasource/ubcRegiDomainDS\" type=\"DataSource\">\n" //

                        + "        JdbcDriver      oracle.jdbc.OracleDriver\n" //

                        + "        JdbcUrl         jdbc:oracle:thin:xxx:1521:SID\n" //

                        + "        JtaManaged      true\n" //

                        + "        logAbandoned    true\n" //

                        + "        userName        user\n" //

                        + "        password        pw\n"

                        + "    </Resource>\n" //

                        + "</Resources>\n";

             

             

                @PersistenceContext(unitName = "ubcRegiDomain")

                protected EntityManager entityManager;

             

             

                @Resource(mappedName = "jdbc:jboss/datasource/ubcRegiDomainDS")

                protected DataSource datasource;

             

             

                /**

                 * Create a ShrinkWrap web archive that will be used by the Arquillian/OpenEJB/Hibernate unit tests

                 * @param caller Calling class so we can find the ArquillianDerbyTestInfo annotation for it

                 * @return

                 */

                public static Archive<?> createDeploymentArchive(final Class<?> caller) { // static methods can't see parent so we have to pass it in

                    String databaseType = "derby";

                    String resourceString = derbyResource;

                    final ArquillianDerbyTestInfo testInfo;

                    if (caller != null) {

                        testInfo = caller.getAnnotation(ArquillianDerbyTestInfo.class);

                        if (testInfo != null && testInfo.databaseType().equals(DatabaseType.ORACLE)) {

                            databaseType = "oracle";

                            resourceString = oracleResource;

                        }

                    } else {

                        testInfo = null;

                    }

             

             

                    final PomEquippedResolveStage mavenResolver = Maven.resolver().loadPomFromFile("pom.xml");

             

             

                    final File[] mockitoFile = mavenResolver.resolve("org.mockito:mockito-all").withoutTransitivity().as(File.class);

                    final WebArchive archive = ShrinkWrap.create(WebArchive.class, "test.war") //

                            .addPackages(true, ArquillianDerbyTest.class.getPackage()) //

                            .addAsLibraries(mockitoFile) //

                            .addAsWebInfResource(new StringAsset(resourceString), "resources.xml") //

                            .addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml") //

                            .addAsWebInfResource("META-INF/" + databaseType + "-persistence.xml", "persistence.xml");

             

             

                    if (testInfo != null) {

                        for (Class<?> bean : testInfo.beans()) {

                            archive.addClass(bean);

                        }

                    }

             

             

                    if (testInfo == null || !testInfo.skipRegiJpa()) {

                        /*

                         * Ugly hack so that Hibernate will see the regiJPA entities.

                         * Hibernate looks at the real file system, based on the location of the persistence.xml file,

                         * so I have to "pollute" the test-classes folder with the entities

                         */

                        final File[] files = mavenResolver.resolve("ca.ubc.sis:ubc-regiJPA").withoutTransitivity().as(File.class);

                        final File destinationDir = new File("target/test-classes");

                        for (final File file : files) {

                            final JavaArchive javaArchive = ShrinkWrap.createFromZipFile(JavaArchive.class, file);

                            javaArchive.as(ExplodedExporter.class).exportExploded(destinationDir, "");

                        }

                    }

             

             

                    /*

                     * final JavaArchive javaArchive = ShrinkWrap.create(JavaArchive.class);

                     * for (File file : files) {

                     * new ZipImporterImpl(javaArchive).importFrom(file);

                     *

                     * //final JavaArchive javaArchive = ShrinkWrap.createFromZipFile(JavaArchive.class, file);

                     * //archive.add(javaArchive, "WEB-INF/classes", StreamExporter.class);

                     * }

                     * archive.merge(javaArchive, "WEB-INF/classes");

                     * // System.out.println(javaArchive.toString(true));

                     * // archive.add(JavaArchive.class).add

                     * //archive.add(javaArchive, "WEB-INF/classes", ZipExporter.class);

                     * // archive.addAsLibraries(files);

                     *

                     */

                    logger.debug(archive.toString(true));

                    return archive;

                }

             

             

            The unit test file looks like:

            @ArquillianDerbyTestInfo(beans= {StudentSearchRepository.class})

            @UsingDataSet({"ca/ubc/sis/services/sisrest/repository/jpa/IT_OamsStudentSearchRepository.xml"})

            public class IT_StudentSearchRepository extends ArquillianDerbyTest {

                @Deployment

                public static Archive<?> deploy() {

                    return createDeploymentArchive(IT_StudentSearchRepository.class);

                }

             

            In the pom.xml I have:

             

                <dependency>

                  <groupId>ca.ubc.sis</groupId>

                  <artifactId>ubc-regiJPA</artifactId>

                  <scope>compile</scope>

                </dependency>

             

            My project layout has:

             

            src/test/resources/META-INF

                 services/

                 derby-persistence.xml

             

            The persistence file looks like:

            <?xml version="1.0" encoding="UTF-8"?>

            <persistence version="2.0"

              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">

             

             

              <persistence-unit name="ubcRegiDomain" transaction-type="JTA">

                <provider>org.hibernate.ejb.HibernatePersistence</provider>

                <jta-data-source>java:jboss/datasource/ubcRegiDomainDS</jta-data-source>

             

                <properties>

                  <property name="hibernate.dialect" value="org.hibernate.dialect.DerbyTenSevenDialect"/>

                  <property name="hibernate.show_sql" value="false"/>

                  <property name="hibernate.format_sql" value="true"/>

                  <property name="hibernate.id.new_generator_mappings" value="true"/>

                  <property name="hibernate.hbm2ddl.import_files" value=""/>

                  <property name="hibernate.hbm2ddl.auto" value="create-drop"/>

                  <property name="hibernate.transaction.jta.platform" value="org.hibernate.service.jta.platform.internal.JBossAppServerJtaPlatform" />

                </properties>

              </persistence-unit>

            </persistence>

             

             

            When I run a test I see:

            DEBUG 2016-03-17 11:35:16 ca.ubc.sis.test.arquillian.ArquillianDerbyTest:136 - test.war:

            /WEB-INF/

            /WEB-INF/classes/

            /WEB-INF/classes/ca/

            /WEB-INF/classes/ca/ubc/

            /WEB-INF/classes/ca/ubc/sis/

            /WEB-INF/classes/ca/ubc/sis/test/

            /WEB-INF/classes/ca/ubc/sis/test/arquillian/

            /WEB-INF/classes/ca/ubc/sis/test/arquillian/ArquillianDerbyTest.class

            /WEB-INF/classes/ca/ubc/sis/test/arquillian/ArquillianDerbyTestBean.class

            /WEB-INF/classes/ca/ubc/sis/test/arquillian/ArquillianDerbyTestInfo.class

            /WEB-INF/classes/ca/ubc/sis/test/arquillian/DatabaseType.class

            /WEB-INF/classes/ca/ubc/sis/services/

            /WEB-INF/classes/ca/ubc/sis/services/sisrest/

            /WEB-INF/classes/ca/ubc/sis/services/sisrest/repository/

            /WEB-INF/classes/ca/ubc/sis/services/sisrest/repository/optimized/

            /WEB-INF/classes/ca/ubc/sis/services/sisrest/repository/optimized/StudentSearchRepository.class

            /WEB-INF/classes/ca/ubc/sis/services/sisrest/repository/optimized/StudentSearchRepository$1.class

            /WEB-INF/classes/ca/ubc/sis/services/sisrest/repository/optimized/StudentSearchRepository$2.class

            /WEB-INF/classes/ca/ubc/sis/services/sisrest/repository/optimized/StudentSearchRepository$3.class

            /WEB-INF/classes/ca/ubc/sis/services/sisrest/repository/optimized/StudentSearchRepository$4.class

            /WEB-INF/classes/ca/ubc/sis/services/sisrest/repository/optimized/StudentSearchRepository$StudentProgram.class

            /WEB-INF/lib/

            /WEB-INF/lib/mockito-all-2.0.2-beta.jar

            /WEB-INF/resources.xml

            /WEB-INF/beans.xml

            /WEB-INF/persistence.xml

            INFO  2016-03-17 11:35:21 org.hibernate.annotations.common.Version:37 - HCANN000001: Hibernate Commons Annotations {4.0.2.Final}

            INFO  2016-03-17 11:35:21 org.hibernate.Version:41 - HHH000412: Hibernate Core {4.2.21.Final}

            INFO  2016-03-17 11:35:21 org.hibernate.cfg.Environment:238 - HHH000206: hibernate.properties not found

            INFO  2016-03-17 11:35:22 org.hibernate.cfg.Environment:345 - HHH000021: Bytecode provider name : javassist

            DEBUG 2016-03-17 11:35:22 org.hibernate.ejb.Ejb3Configuration:529 - Processing PersistenceUnitInfo [

              name: ubcRegiDomain

              persistence provider classname: org.hibernate.ejb.HibernatePersistence

              classloader: org.apache.openejb.arquillian.openejb.SWClassLoader@10afe71a

              Temporary classloader: org.apache.openejb.core.TempClassLoader@7c8c70d6

              excludeUnlistedClasses: false

              JTA datasource: org.apache.openejb.resource.jdbc.dbcp.BasicManagedDataSource@6b3f6585

              Non JTA datasource: org.apache.openejb.resource.jdbc.dbcp.BasicDataSource@1b5c3e5f

              Transaction type: JTA

              PU root URL: file:/W:/Perforce/lindholm/FEATURE_JAVA_JBOSS/sis/services/sisrest/sisrest-service-war/target/test-classes/

              Shared Cache Mode: UNSPECIFIED

              Validation Mode: AUTO

              Jar files URLs []

              Managed classes names []

              Mapping files names []

              Properties [

              hibernate.id.new_generator_mappings: true

              hibernate.dialect: org.hibernate.dialect.DerbyTenSevenDialect

              hibernate.show_sql: false

              hibernate.hbm2ddl.import_files:

              hibernate.hbm2ddl.auto: update

              hibernate.format_sql: true

              hibernate.transaction.jta.platform: org.apache.openejb.hibernate.OpenEJBJtaPlatform]

            DEBUG 2016-03-17 11:35:22 org.hibernate.ejb.Ejb3Configuration:852 - Detect class: true; detect hbm: true

            DEBUG 2016-03-17 11:35:22 org.hibernate.ejb.Ejb3Configuration:852 - Detect class: true; detect hbm: true

            DEBUG 2016-03-17 11:35:22 org.hibernate.ejb.packaging.AbstractJarVisitor:126 - Searching mapped entities in jar/par: file:/W:/Perforce/lindholm/FEATURE_JAVA_JBOSS/sis/services/sisrest/sisrest-service-war/target/test-classes/


            Thanks