0 Replies Latest reply on Oct 2, 2012 9:58 AM by dgmora

    Testing persistence EJB with arquillian in multimodule maven projects

    dgmora

      I want to use Arquillian to be able to access the database while using JUnit tests. I have been able to access to an EntityManager, but I need to to something more complex.

       

      The project has several modules and is packaged as a ear.

       

      - In ModuleA I have a Local and Remote interface of an EJB, which access to the database with an EntityManager.

       

               public interface PersistenceLocal {

                   public <T> T insert(T object);

                   //....

               }

      - In ModuleB I have one class that implements both of these interfaces

       

               @Stateless

               @Local(ProcessServiceLocal.class)

               @Remote(ProcessServiceRemote.class)

               public class PersistenceImpl implements ProcessServiceRemote, ProcessServiceRemote{

       

                   @PersistenceContext(unitName = PERSISTENCE_UNIT)

                   private EntityManager entityManager;

       

                   public <T> T insert(T object) {

                       entityManager.persist(object);

                       entityManager.flush();

                       return object;

                   }

                   //....

              }

       

      - ModuleB depends on ModuleA via Maven

      - I'm trying to access the database in a test in ModuleC. This module depends via Maven on ModuleA and ModuleB with scope provided.

       

      .

       

          @RunWith(Arquillian.class)

          public class testTest {

       

                  @Deployment

                  public static Archive<?> createDeployment() {

                      File modA = Maven.resolver().resolve("group.id:modA:0.1")

                         .withTransitivity().asSingle(File.class);

       

                      File modB = Maven.resolver().resolve("group.id:modB:0.1")

                         .withTransitivity().asSingle(File.class);

                      //not sure of this step, but I'm just adding some libs.

       

                      //If I don't add somewhere the test I have some

                      //error bc it cannot be found

                      JavaArchive test = ShrinkWrap.create(

                          JavaArchive.class, "sth.jar").addClass(testTest.class);

       

                       EnterpriseArchive ear = ShrinkWrap.create(EnterpriseArchive.class,"test.ear")

                          .addAsLibrary(api)

                          .addAsModule(test)

                          .addAsModule(ejb);

       

                       return ear;

       

                  }

       

              @EJB

              PersistenceLocal persistence;

       

              @Test

              public void testPersistance() {

                  Assert.assertNotNull(persistence);

              }

          }

      The ear deployed with this config is the following:

       

      All three modules are packaged as jars inside the ear, but ModuleA is inside the lib folder of the ear. I am using arquillian with a remote JBoss 7.0.1. arquillian.xml and persistence.xml are correctly set up, as I can access with EntityManager.

       

       

      What I don't know is what should I add to the packaging in order to make it work. I'm really struggling with this, because I am not sure which is the problem, since all the classes are in different modules and I'm new to Arquillian.

       

      Error I get right now is:

       

          org.jboss.arquillian.container.spi.client.container.DeploymentException: Could not deploy to container

       

          Caused by: java.lang.Exception: {

          "Failed services" => {"jboss.deployment.subunit.\"test.ear\".\"modB-357922373339836768.jar\".POST_MODULE" => "org.jboss.msc.service.StartException in service jboss.deployment.subunit.\"test.ear\".\"modB-357922373339836768.jar\".POST_MODULE: Failed to process phase POST_MODULE of subdeployment \"modB-357922373339836768.jar\" of deployment \"test.ear\""},

          "Services with missing/unavailable dependencies" => [

              "jboss.naming.context.java.comp.test.test.test.ValidatorFactory missing [ jboss.naming.context.java.module.test.test ]",

              "jboss.naming.context.java.comp.test.test.test.Validator missing [ jboss.naming.context.java.module.test.test ]"

          ]

          }

      And looking into the server log:

       

          Caused by: org.jboss.as.server.deployment.DeploymentUnitProcessingException: Could not load EJB class group.id.ejb.persistence.impl.persistenceImpl

          at org.jboss.as.ejb3.deployment.processors.BusinessViewAnnotationProcessor.getEjbClass(BusinessViewAnnotationProcessor.java:197)

          at org.jboss.as.ejb3.deployment.processors.BusinessViewAnnotationProcessor.deploy(BusinessViewAnnotationProcessor.java:77)

          at org.jboss.as.server.deployment.DeploymentUnitPhaseService.start(DeploymentUnitPhaseService.java:115)

          ... 5 more

          Caused by: java.lang.ClassNotFoundException: group.id.ejb.persistence.impl.persistenceImpl from [Module "deployment.test.ear.modB-6953783656278818077.jar:main" from Service Module Loader]

          at org.jboss.modules.ModuleClassLoader.findClass(ModuleClassLoader.java:191)

          at org.jboss.modules.ConcurrentClassLoader.performLoadClassChecked(ConcurrentClassLoader.java:358)

          at org.jboss.modules.ConcurrentClassLoader.performLoadClass(ConcurrentClassLoader.java:307)

          at org.jboss.modules.ConcurrentClassLoader.loadClass(ConcurrentClassLoader.java:101)

          at org.jboss.as.ejb3.deployment.processors.BusinessViewAnnotationProcessor.getEjbClass(BusinessViewAnnotationProcessor.java:195)

          ... 7 more

      I looked on the temporal jar generated (which ends up stored somewhere on the disk) and the persistenceImpl.class is correctly located in the jar. Maybe some classloading isolation issue?

      Content of the ear generated by Shrinkwrap:

       

          [context=/test.jar]

          [context=/lib/modA.jar]

          [context=/modB.jar]

       

      I have looked inside the jar, and maybe there is some issue with the slashes and backslashes mix?

       

      BasicPath [context=/group\id\ejb\persistence\impl\PersistenceImpl.class]