13 Replies Latest reply on Sep 29, 2017 10:20 AM by med.amd

    Arquillian test with real EAR from build

    rick-rainer.ludwig

      The topic has maybe something to do with the thread https://community.jboss.org/thread/200399, but it does not really solve my issue, yet.

       

      I want to test an Java EE application with Arquillian. A simple setup is working to put some test classes onto the server managed by Arquillian to test them. So, the general setup of Arquillian is working. When I put all needed classes into WebArchive, the tests are also running.

       

      For better testing and to avoid to much code, I thought, I could take an EAR file directly from the build process. I only want to add my test classes.

       

      I tried to put this into action with the deployment method:

       

      @Deployment
      public static EnterpriseArchive createDeployment() {
         
      File earFile = ...
         
      EnterpriseArchive archive = ShrinkWrap.createFromZipFile(EnterpriseArchive.class, earFile);
         
      return archive;
      }

       

      I am able to put the EAR via Arquillian to JBoss. I see the deployment and there are no errors during deployment. Only Arquillian returns with an error that it can not find the test class, which is obviously ok and expected.

       

      Now is the question where to put the test class to. I can put the test class into the test.war put into the EAR by Arquillian by using archive.addAsModule(WebArchive<?>), but I get an ArquillianServletRunner not found exception due to some missing entries in the application.xml as I assume. When I put the test classes into JAR files as module or library the test classes are not found when put as module or the injects in the test classes do not work when put as libraries into the EAR due to dependency issues within the EAR file. So I got stuck...

       

      Now, where do I have to put the test classes to??? Do I need some additional information within the EnterpriseArchive? What is needed and how do I put them to? Is this maybe a missing feature?

       

      My arquillian.xml:

       

      <?xml version="1.0" encoding="UTF-8"?>
      <arquillian xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         
      xmlns="http://jboss.org/schema/arquillian"
         
      xsi:schemaLocation="http://jboss.org/schema/arquillian http://jboss.org/schema/arquillian/arquillian_1_0.xsd">

        
      <defaultProtocol type="Servlet 3.0" />

         
      <container qualifier="jboss7" default="true">
             
      <configuration>
                 
      <property name="jbossHome">${cargo.dir}/jboss-as-dist-7.1.1.Final/jboss-as-7.1.1.Final</property>
             
      </configuration>
         
      </container>

         
      <engine>
             
      <property name="deploymentExportPath">target/deployments</property>
         
      </engine>

      </arquillian>

       

      I appriciate any help on this. Thanks in advance!

        • 1. Re: Arquillian test with real EAR from build
          aslak

          What is the structure of the EAR you import ?

          • 2. Re: Arquillian test with real EAR from build
            stardestroyer

            Rick-Rainer,

             

            You're quite right, if you create a separate WAR file with the tests, you will get some not-found exceptions because any new WAR file must be listed in application.xml, an artifact of the EAR.  You could try editing that file (either directly or with shrinkwrap-descriptors), but you will very likely run into classloading issues as test classes won't be able to "see into" the classes of the application's WAR.

             

            Long story short, I think you would need to rethink the strategy of taking the EAR file directly from the build process.  You either need to include the tests into the build -- i.e. building a different copy of the EAR with your test classes included -- or modify the EAR by injecting your classes into the WAR inside the EAR.  For the second approach, extract the WAR out of the EAR, add your test classes (it would be easier with JEE6/Servlet 3.0 because less metadata needs to be modified), then put the WAR back into the EAR. 

             

            • 3. Re: Arquillian test with real EAR from build
              rick-rainer.ludwig

              I use the EAR and I perform some transformation on the content like changing the application.xml and the WARs included. It is quite complex to do, but the tests are good at the end and they are running in the server... ;-)

              • 4. Re: Arquillian test with real EAR from build
                aslak

                just to note, ShrinkWrap Descriptors should help with the descriptors manipulations. https://github.com/shrinkwrap/descriptors

                 

                Example: https://github.com/shrinkwrap/descriptors/blob/master/test/src/test/java/org/jboss/shrinkwrap/descriptor/test/application6/ApplicationDescriptorTestCase.java

                 

                Similar Descriptors exists for web.xml, ejb-jar.xml, beans.xml, faces-config.xml, jsp-tags, persistence.xml........

                • 5. Re: Arquillian test with real EAR from build
                  tomeicher

                  Hey Rick-Rainer,

                  were you able to get this working gracefully in the end?

                  I'm looking into doing something very similar...

                  I was thinking I could just add the test.jar to the EAR using an ant task, putting an alternate application.xml like here:

                  http://stackoverflow.com/questions/12059046/ant-ear-update-without-full-exploding-ear?rq=1

                  Any more lessons learned ?

                  Cheers, Tom.

                  • 6. Re: Arquillian test with real EAR from build
                    karomann

                    Hi Tom,

                    following works for me:

                     

                    public static EnterpriseArchive getApplicationEar(Class<?> testClass) {

                     

                                        EnterpriseArchive ear = ShrinkWrap.create(EnterpriseArchive.class, "application-ear.ear")

                                                            .as(ZipImporter.class)

                                                            .importFrom(new File("../application-ear/target/application-ear-1.0-SNAPSHOT.ear"))

                                                            .as(EnterpriseArchive.class);

                     

                     

                      //now add the testClass and any test util classes that are not in the archive

                                        JavaArchive testLibraryHelper = ShrinkWrap.create(JavaArchive.class)

                                                            .addClass(testClass)

                                                            .addPackage(MiscUtil.class.getPackage())

                                                            .addPackage(some.other.UtilClass.class.getPackage())

                     

                     

                                                            //now for CDI working in testLibraryHelper

                                                            .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml");

                     

                     

                                        ear.addAsLibrary(testLibraryHelper);

                     

                                        return ear;

                              }

                    • 7. Re: Arquillian test with real EAR from build
                      tomeicher

                      Hey Kamil, thanks, in the end it's easier than I feared :-)

                      It even works to address the existing jar/war inside the ear and just add the classes there:

                       

                      EnterpriseArchive ear = ShrinkWrap.create(ZipImporter.class, "eee.ear")

                        .importFrom(new File("../dist/eee.ear")).as(EnterpriseArchive.class) ;

                       

                      WebArchive war = ear.getAsType(WebArchive.class, "/eee-war.war");

                      war.addPackage("com.eee.testutils");

                       

                      In my case, I had to add some test classes to the EJB layer (jar) and some to the web layer (war) so that

                      everybody finds the classes needed...

                       

                      Cheers, Tom.

                      • 8. Re: Arquillian test with real EAR from build
                        sarah333

                        it didnt work for me i get this:

                         

                        java.lang.IllegalArgumentException: ArquillianServletRunner not found. Could not determine ContextRoot from ProtocolMetadata, please contact DeployableContainer developer.

                                  at org.jboss.arquillian.protocol.servlet.ServletUtil.determineBaseURI(ServletUtil.java:64)

                                  at org.jboss.arquillian.protocol.servlet.ServletURIHandler.locateTestServlet(ServletURIHandler.java:60)

                                  at org.jboss.arquillian.protocol.servlet.ServletMethodExecutor.invoke(ServletMethodExecutor.java:84)

                                  at org.jboss.arquillian.container.test.impl.execution.RemoteTestExecuter.execute(RemoteTestExecuter.java:120)

                                  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

                                  at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)

                                  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

                                  at org.jboss.arquillian.core.impl.ObserverImpl.invoke(ObserverImpl.java:94)

                                  at org.jboss.arquillian.core.impl.EventContextImpl.invokeObservers(EventContextImpl.java:99)

                                  at org.jboss.arquillian.core.impl.EventContextImpl.proceed(EventContextImpl.java:81)

                                  at org.jboss.arquillian.core.impl.ManagerImpl.fire(ManagerImpl.java:135)

                                  at org.jboss.arquillian.core.impl.ManagerImpl.fire(ManagerImpl.java:115)

                                  at org.jboss.arquillian.core.impl.EventImpl.fire(EventImpl.java:67)

                                  at org.jboss.arquillian.container.test.impl.execution.ClientTestExecuter.execute(ClientTestExecuter.java:57)

                                  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

                                  at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)

                                  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

                                  at org.jboss.arquillian.core.impl.ObserverImpl.invoke(ObserverImpl.java:94)

                                  at org.jboss.arquillian.core.impl.EventContextImpl.invokeObservers(EventContextImpl.java:99)

                                  at org.jboss.arquillian.core.impl.EventContextImpl.proceed(EventContextImpl.java:81)

                                  at org.jboss.arquillian.container.test.impl.client.ContainerEventController.createContext(ContainerEventController.java:142)

                                  at org.jboss.arquillian.container.test.impl.client.ContainerEventController.createTestContext(ContainerEventController.java:129)

                                  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

                                  at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)

                                  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

                                  at org.jboss.arquillian.core.impl.ObserverImpl.invoke(ObserverImpl.java:94)

                                  at org.jboss.arquillian.core.impl.EventContextImpl.proceed(EventContextImpl.java:88)

                                  at org.jboss.arquillian.test.impl.TestContextHandler.createTestContext(TestContextHandler.java:89)

                                  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

                                  at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)

                                  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

                                  at org.jboss.arquillian.core.impl.ObserverImpl.invoke(ObserverImpl.java:94)

                                  at org.jboss.arquillian.core.impl.EventContextImpl.proceed(EventContextImpl.java:88)

                                  at org.jboss.arquillian.test.impl.TestContextHandler.createClassContext(TestContextHandler.java:75)

                                  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

                                  at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)

                                  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

                                  at org.jboss.arquillian.core.impl.ObserverImpl.invoke(ObserverImpl.java:94)

                                  at org.jboss.arquillian.core.impl.EventContextImpl.proceed(EventContextImpl.java:88)

                                  at org.jboss.arquillian.test.impl.TestContextHandler.createSuiteContext(TestContextHandler.java:60)

                                  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

                                  at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)

                                  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

                                  at org.jboss.arquillian.core.impl.ObserverImpl.invoke(ObserverImpl.java:94)

                                  at org.jboss.arquillian.core.impl.EventContextImpl.proceed(EventContextImpl.java:88)

                                  at org.jboss.arquillian.core.impl.ManagerImpl.fire(ManagerImpl.java:135)

                                  at org.jboss.arquillian.test.impl.EventTestRunnerAdaptor.test(EventTestRunnerAdaptor.java:111)

                                  at org.jboss.arquillian.junit.Arquillian$6.evaluate(Arquillian.java:263)

                                  at org.jboss.arquillian.junit.Arquillian$4.evaluate(Arquillian.java:226)

                                  at org.jboss.arquillian.junit.Arquillian.multiExecute(Arquillian.java:314)

                                  at org.jboss.arquillian.junit.Arquillian.access$100(Arquillian.java:46)

                                  at org.jboss.arquillian.junit.Arquillian$5.evaluate(Arquillian.java:240)

                                  at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:76)

                                  at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)

                                  at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)

                                  at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)

                                  at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)

                                  at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)

                                  at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)

                                  at org.jboss.arquillian.junit.Arquillian$2.evaluate(Arquillian.java:185)

                                  at org.jboss.arquillian.junit.Arquillian.multiExecute(Arquillian.java:314)

                                  at org.jboss.arquillian.junit.Arquillian.access$100(Arquillian.java:46)

                                  at org.jboss.arquillian.junit.Arquillian$3.evaluate(Arquillian.java:199)

                                  at org.junit.runners.ParentRunner.run(ParentRunner.java:236)

                                  at org.jboss.arquillian.junit.Arquillian.run(Arquillian.java:147)

                                  at org.junit.runner.JUnitCore.run(JUnitCore.java:157)

                                  at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:76)

                                  at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:195)

                                  at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:63)

                                  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

                                  at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)

                                  at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)

                        • 9. Re: Arquillian test with real EAR from build
                          karomann

                          Please try to run the test again. I get this error on JBoss 7.1.x always when I run an Arquillian test for the first time after JBoss has been restarted. But when I run the test again it works like a charm

                          • 10. Re: Arquillian test with real EAR from build
                            tomeicher

                            Make sure to delete all existing of your .jar/.war/.ear from the server install.

                            For me, this particular error was always caused by "leftover artifacts".

                            Cheers, Tom.

                            • 11. Re: Arquillian test with real EAR from build
                              sarah333

                              I did but I still getting the same error.  I'm running my tests in embedded glassfish . here is my code:

                               

                              @Deployment

                                  public static EnterpriseArchive createDeployment() {

                               

                               

                                      JavaArchive common = ShrinkWrap.create(JavaArchive.class, "arquillian-common.jar")

                                              .addClasses(

                                                      Account.class,

                                                      Workspace.class,

                                                      Credential.class

                                              );

                               

                               

                                      JavaArchive ejb = ShrinkWrap.create(JavaArchive.class, "arquillian-tests.jar")

                               

                               

                                              .addClasses(

                                                      TestEJBBean.class,                       

                                                      UserBean.class,                    

                                              )

                                              .addAsResource("test-persistence.xml", "META-INF/persistence.xml")

                                              .addAsManifestResource("WEB-INF/sun-web.xml")

                                              .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml");

                               

                               

                                      EnterpriseArchive ear = ShrinkWrap.create(EnterpriseArchive.class, "arquillian-tests.ear")

                                                                       .as(ZipImporter.class)

                                                                       .importFrom(new File("arquillian-tests/target/arquillian-tests-2.0-SNAPSHOT.ear"))

                                                                       .as(EnterpriseArchive.class)

                                                                       .addAsDirectory("lib")

                                                                       .addAsLibrary(common)

                                                                       .addAsLibrary(ejb);

                               

                                      return ear;

                               

                               

                                  }

                              I want to produce this architecture:

                               

                              myproject-ear

                                                   -myproject.jar (contains beans)

                                                   -lib (that should contain all the librairies jars)

                                                   -META-INF

                                                                    - application.xml

                                                                    - sun-application.xml

                              • 12. Re: Arquillian test with real EAR from build
                                karomann

                                You may also check this thread:

                                 

                                https://community.jboss.org/thread/173340, it seems its author had a similar problem.

                                 

                                Unfortunately, it seems that your problem is glassfish-and-arquillian-integration-related issue.

                                • 13. Re: Arquillian test with real EAR from build
                                  med.amd

                                  What about this solution here?

                                   

                                  Is it suitable for legacy applications?