2 Replies Latest reply on Aug 13, 2014 3:24 PM by philipp91

    How to test an EJB with the following structure: EAR + WAR + JAR's?

    juliocspires

      Hi,

      I have the following project structure:

       

      EAR

      • WAR
      • EJB (JAR) --- Test Here
      • Persistence (JAR)
      • Entities (JAR)

       

      I want to test the Beans present in EJB (JAR), but I've tried different ways with ShrinkWrap and none worked.

      Questions that I have:

       

      1) What is the standard structure for testing the EJB (JAR) (knowing that it depends only on others JAR's, not WAR/EAR) ?

       

      2) What should I use: JavaArchive, WebArchive or EnterpriseArchive?

       

      Scenario:

      • JDK 1.8.0_05
      • Wildfly-8.0.0.Final
      • Arquillian 1.1.4.Final
      • Shrinkwrap 2.2.0-alpha-2

       

      @Deployment
      public static Archive<?> getDeployment() {
      //Load ALL dependencies
      File[] files = Maven.configureResolver()
                      .workOffline()
                      .withMavenCentralRepo(false)
                      .withClassPathResolution(true)
                      .loadPomFromFile("pom.xml")
                      .importDependencies(ScopeType.PROVIDED, ScopeType.TEST, ScopeType.RUNTIME, ScopeType.COMPILE)
                      .resolve().withTransitivity().asFile();
      
      
      
      //Create EJB
      JavaArchive ejb = ShrinkWrap.create(JavaArchive.class, "ejb.jar");
      ejb.addAsManifestResource(EmptyAsset.INSTANCE, ArchivePaths.create("beans.xml"));
      
      //ADD ALL dependencies in EJB (is that correct??)
      for (File file : files) {
          ejb.addAsResource(file);
      }
      
      return ejb;
      }
      
      
      
      

       

      ERROR:

       

      1A) Why test.war? I'm testing an EJB that has no relationship with .WAR

       

      1B) Caused by: java.util.ServiceConfigurationError: javax.servlet.ServletContainerInitializer: Provider com.sun.faces.config.FacesInitializer not found

      Why an error of JSF / Faces?

       

      ERROR [org.jboss.msc.service.fail] MSC000001: Failed to start service jboss.deployment.unit."test.war".INSTALL: org.jboss.msc.service.StartException in service jboss.deployment.unit."test.war".INSTALL: JBAS018733: Failed to process phase INSTALL of deployment "test.war"

          at org.jboss.as.server.deployment.DeploymentUnitPhaseService.start(DeploymentUnitPhaseService.java:166) [wildfly-server-8.0.0.Final.jar:8.0.0.Final]

          at org.jboss.msc.service.ServiceControllerImpl$StartTask.startService(ServiceControllerImpl.java:1948) [jboss-msc-1.2.0.Final.jar:1.2.0.Final]

          at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1881) [jboss-msc-1.2.0.Final.jar:1.2.0.Final]

          at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [rt.jar:1.8.0_05]

          at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [rt.jar:1.8.0_05]

          at java.lang.Thread.run(Thread.java:745) [rt.jar:1.8.0_05]

      Caused by: java.util.ServiceConfigurationError: javax.servlet.ServletContainerInitializer: Provider com.sun.faces.config.FacesInitializer not found

          at java.util.ServiceLoader.fail(ServiceLoader.java:239) [rt.jar:1.8.0_05]

          at java.util.ServiceLoader.access$300(ServiceLoader.java:185) [rt.jar:1.8.0_05]

          at java.util.ServiceLoader$LazyIterator.nextService(ServiceLoader.java:372) [rt.jar:1.8.0_05]

          at java.util.ServiceLoader$LazyIterator.next(ServiceLoader.java:404) [rt.jar:1.8.0_05]

          at java.util.ServiceLoader$1.next(ServiceLoader.java:480) [rt.jar:1.8.0_05]

          at org.wildfly.extension.undertow.deployment.ServletContainerInitializerDeploymentProcessor.deploy(ServletContainerInitializerDeploymentProcessor.java:112)

          at org.jboss.as.server.deployment.DeploymentUnitPhaseService.start(DeploymentUnitPhaseService.java:159) [wildfly-server-8.0.0.Final.jar:8.0.0.Final]

          ... 5 more

        • 1. Re: How to test an EJB with the following structure: EAR + WAR + JAR's?
          robert.panzer

          A JavaArchive is not deployable per se.

           

          Return either a WebArchive when testing the JavaEE Web Profile or an EnterpriseArchive when testing the Full Profile:

          return ShrinkWrap.create(EnterpriseArchive.class).addAsModule(ejbjar)

          or

          return ShrinkWrap.create(WebArchive.class).addAsLibrary(ejbjar)

           

          If Arquillian uses the Servlet protocol it either requires a test.war in the ear or a web fragment in the WebArchive (or in the already existing war inside the ear.)

           

          editing here here is no fun on mobile...

          • 2. Re: How to test an EJB with the following structure: EAR + WAR + JAR's?
            philipp91

            I have a very similar problem with Camunda BPM. The same problem does not occur when deploying the application manually.

             

            This is the exception when Arquillian tries to deploy the application on WildFly:

             

            ERROR [org.jboss.msc.service.fail] MSC000001: Failed to start service jboss.deployment.unit."someFile.war".INSTALL: org.jboss.msc.service.StartException in service jboss.deployment.unit."someFile.war".INSTALL: JBAS018733: Failed to process phase INSTALL of deployment "someFile.war"

                    at org.jboss.as.server.deployment.DeploymentUnitPhaseService.start(DeploymentUnitPhaseService.java:166) [wildfly-server-8.1.0.Final.jar:8.1.0.Final]

                    at org.jboss.msc.service.ServiceControllerImpl$StartTask.startService(ServiceControllerImpl.java:1948) [jboss-msc-1.2.0.Final.jar:1.2.0.Final]

                    at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1881) [jboss-msc-1.2.0.Final.jar:1.2.0.Final]

                    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [rt.jar:1.8.0_05]

                    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [rt.jar:1.8.0_05]

                    at java.lang.Thread.run(Thread.java:745) [rt.jar:1.8.0_05]

            Caused by: java.util.ServiceConfigurationError: javax.servlet.ServletContainerInitializer: Provider org.camunda.bpm.application.impl.ServletProcessApplicationDeployer not found

                    at java.util.ServiceLoader.fail(ServiceLoader.java:239) [rt.jar:1.8.0_05]

                    at java.util.ServiceLoader.access$300(ServiceLoader.java:185) [rt.jar:1.8.0_05]

                    at java.util.ServiceLoader$LazyIterator.nextService(ServiceLoader.java:372) [rt.jar:1.8.0_05]

                    at java.util.ServiceLoader$LazyIterator.next(ServiceLoader.java:404) [rt.jar:1.8.0_05]

                    at java.util.ServiceLoader$1.next(ServiceLoader.java:480) [rt.jar:1.8.0_05]

                    at org.wildfly.extension.undertow.deployment.ServletContainerInitializerDeploymentProcessor.deploy(ServletContainerInitializerDeploymentProcessor.java:112)

                    at org.jboss.as.server.deployment.DeploymentUnitPhaseService.start(DeploymentUnitPhaseService.java:159) [wildfly-server-8.1.0.Final.jar:8.1.0.Final]

                    ... 5 more

             

            I already digged into it and debugged the service loading of WildFly/Undertow. The exception occurs because the Hibernate (!!) JAR, which is also part of the deployment, contains a META-INF/services folder, just like the Camunda JAR does. Inside the linkage of the Hibernate module (see source of org.jboss.modules.Module), there is that mapping of paths (like /com/some/thing) to class loaders, that are responsible for this path.

            Of course, all "/org/camunda" paths don't exist for the linkage of the Hibernate module (why would they...). BUT: "META-INF/services" for the Hibernate module references the following class loaders:

            META-INF/services=[

            local loader for ModuleClassLoader for Module "org.apache.xerces:main" from local module loader @48a0bf7d,

            org.jboss.modules.ClassLoaderLocalLoader@469ccc8b,

            local loader for ModuleClassLoader for Module "sun.jdk:main" from local module loader @48a0bf7d,

            local loader for ModuleClassLoader for Module "org.hibernate.validator:main" from local module loader @48a0bf7d]

             

            Note the ClassLoaderLocalLoader in there, which references to the main class loader of the web application (deployed by Arquillian). This class loader on the other hand has references to *all* JAR files (I don't know if this is how it is supposed to be, but that's the case with my application that runs fine without Arquillian). That's why the "META-INF/services/javax.servlet.ServletContainerInitializer" file inside the Camunda JAR is found when the "META-INF/services" path is queried for the Hibernate archive. The file is then loaded and the ServiceLoader tries to resolve the class referenced in the file. Since the class belongs to Camunda, there is no path for its package inside the Hibernate package. Note that the *classloaders* of the Hibernate package would be able to load the class (since the web-application classloader is among them), but there is *no* path reference for Camunda packages in the linkage of the Hibernate module, so that the class lookup fails without consulting any classloaders.

             

            I don't know where/by which code the "META-INF/services" reference is created and why the web-application class-loader is in there. I didn't file any bug report yet, because I am not sure if this is due to my (erroneous) deployment configuration with Arquillian -- or an Arquillian bug, or an Undertow bug, or a JBoss modules bug, ...

             

            Thank you for any help!