8 Replies Latest reply on Apr 15, 2012 8:49 AM by bertil.karlsson

    "Crossing" jar boundaries in a ShrinkWrap WebArchive when using Weld

    bertil.karlsson

      Let me start with saying that I definitelly qualify as a Aquillian noob!

       

      I have been able to follow the Getting started guide without problems, but when I try to convert that into a real test case I get into trouble ...

       

      I have a WebArchive that I setup according to following:

       

      {code}

      @Deployment

      public static WebArchive createWebDeployment() {

           String aPom = "pom.xml";

           MavenDependencyResolver aResolver = DependencyResolvers.use(MavenDependencyResolver.class).loadMetadataFromPom(aPom);

           WebArchive aWebArchive = ShrinkWrap.create(WebArchive.class, "test.war")

                                    .addClass(Resources.class) // Adds EntityManager through usage of @Produces

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

                                    .addAsManifestResource("MANIFEST.MF") // Adds classpath handling according JBoss7 concept

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

                     .addAsLibraries(aResolver.artifact("com.metria.saerimner.system.server:saerimner-logger").resolveAsFiles())

                                    .addAsLibraries(aResolver.artifact("com.metria.saerimner.system.server:saerimner-service").resolveAsFiles());

                System.out.println(aWebArchive.toString(true));

                return aWebArchive;

      }

      {code}

       

      In the artifact saerimner-logger I have a @Produces definition of a qualified logger according to:

      {code}

      @Produces

      @SaerimnerLogger

      Logger createLogger(InjectionPoint injectionPoint) {

           return Logger.getLogger(injectionPoint.getMember().getDeclaringClass().getName());

      }

      {code}

       

      In the artifact saerimner-service I have an SLSB that I wan't to test. This SLSB is injecting a EntityManager among other things.

       

      In the Aquillian test class I have:

      {code}

      @Inject

      SaerimnerServiceBean itsService;

      {code}

       

      I have a pom.xml according to the Getting started guide, except that I am using weld-core:1.1.7.Final (for the embedded test)

       

      If I run according to the profile arquillian-jbossas-managed (see Getting started guide), i.e. remote jboss (7.1.1.Final), everything works!

       

      But if I try profile arquillian-weld-ee-embedded (embedded conatiner) I get an error:

       

      Tests in error:

        com.metria.saerimner.service.ServiceIntegrationTest: WELD-001408 Unsatisfied dependencies for type [SaerimnerServiceBean] with qualifiers [@Default] at injection point [[field] @Inject com.metria.saerimner.service.ServiceIntegrationTest.itsService]

       

      I have tried to add the SaerimnerServiceBean.class to the test archive, but encounters the following:

       

      org.jboss.weld.exceptions.DeploymentException: WELD-001408 Unsatisfied dependencies for type [Logger] with qualifiers [@SaerimnerLogger] at injection point [[field] @Inject @SaerimnerLogger private transient com.metria.saerimner.service.SaerimnerServiceBean.itsLog]

       

      And on top of that I found that the remote profile is then not working anymore due to duplcate definitions of classes (both in a jar and included with the WebArchive).

       

      Am I expecting to much here or am I doing a classic noob "error"??

       

      I have also tried to clean up a bit so I cannot promise that a compiler will not complain over my example here :-)

       

      The reason I'm going for the "jar-version" of a testcase, instead of including classes, is that we have a rather large framework in place that needs to be in place too and also the JBoss7 classpath handling are in  place in the jar's.

       

      Perhaps I should say that we are planning on using Aquillian for "intergration" tests and as such it has to be fully functional when executing the tests

       

      Any pointers appreciated!! For now I will stick to the remote version only ...

       

       

      BRGDS

       

      /B

        • 1. Re: "Crossing" jar boundaries in a ShrinkWrap WebArchive when using Weld
          aslak

          In general, the weld-ee-container is CDI only, so no JPA, no EJB.

           

          You can test the pure CDI model in it, Beans, Extensions, Events, Qualifiers, Alternatives, Stereotypes etc, but anything that goes cross technology, e.g. JPA or EJB you need to use a container that support them all. Managed/Remote JBossAS/GlassFish containers.

          1 of 1 people found this helpful
          • 2. Re: "Crossing" jar boundaries in a ShrinkWrap WebArchive when using Weld
            bertil.karlsson

            Thanks for the quick answer! Me like :-)

             

            Ok, sounds resonable!

             

            But is there an explanation of why @Inject and @Produces generates different results based on if they are added with WebArchive#addClass or if they are added as jar's with WebArchive#addAsLibraries??

             

            If I WebArchive#addClass(SaerimnerServiceBean.class) it will be injected in the testclass (at least the proxy will)

             

            If I WebArchive#addAsLibraries(...) with the SaerimnerServiceBean.class included in a jar I will get the error message about Unsatisfied dependencies

             

            Is this related to the fact that it is an SLSB?

             

            The same goes for @Produces where if I add a class with WebArchive#addClass that has a definition of @Produces it works, but if the @Produces is in a jar, it doesn't


            Only trying to understand what's happening here ...

             

            Hmmm, I think I will try to create a separate "test" project to more accuratelly be able to see what's happening here ...

             

             

            BRGDS

             

            /B


            • 3. Re: "Crossing" jar boundaries in a ShrinkWrap WebArchive when using Weld
              aslak

              The problem there is that the weld-ee-container doesn't really do a good job of handling your deployed Archive(no direct classloading). Specially in the case where what you add as Libraries to a war are packaged jar files.

               

              addAsLibrary(ShrinkWrap.create(JavaArchive.class).addClasses(x, y, z)) should work

               

              addAsLibrary(new FIle("my_packaged.jar")) does current not work

              1 of 1 people found this helpful
              • 4. Re: "Crossing" jar boundaries in a ShrinkWrap WebArchive when using Weld
                bertil.karlsson

                Thank's for the pointer!

                 

                I think I got something working now (at least for my purpose )

                 

                I'm using the following to load all my dependent jar's:

                 

                MavenDependencyResolver aResolver = DependencyResolvers.use(MavenDependencyResolver.class).loadMetadataFromPom("pom.xml");

                WebArchive aArchive = ShrinkWrap.create(WebArchive.class, "test-greeter.war").addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml");

                File[] files = aResolver.artifact("com.metria.arquillian:service").resolveAsFiles();

                for (File file : files) {

                    ZipFile existingZipFile = new JarFile(file);

                    // Import from the Filesystem as a real JAR

                    JavaArchive archive = ShrinkWrap.create(ZipImporter.class, file.getName())

                        .importFrom(existingZipFile)

                        .as(JavaArchive.class);

                    aArchive.addAsLibraries(archive);

                }

                 

                This works for me both in embedded and remote profiles ...

                 

                BRGDS

                 

                /B

                • 5. Re: "Crossing" jar boundaries in a ShrinkWrap WebArchive when using Weld
                  bmajsak

                  I think you don't need to convert files to archives in order to add it as library. ShrinkWrap handles it for you

                  {code:java} T addAsLibraries(File... resources)

                  {code}

                  • 6. Re: "Crossing" jar boundaries in a ShrinkWrap WebArchive when using Weld
                    bertil.karlsson

                    Actually that was my first try (at least I thought so ), but that didn't work:

                     

                    snip...

                    .addAsLibraries(aResolver.artifact("com.metria.saerimner.system.server:saerimner-logger").resolveAsFiles())

                    snip...

                     

                    After using the pointer from Aslak I got it working. I then digged a little bit into ShrinWrap code and found that it's being handled different depending on if I'm using an Archive or not.

                     

                    This lead me to the "last" version that I posted. However, being a noob in the area of Arquillian (ShrinkWrap included), can be a factor in the solution I got working. Better ways probably exists ...

                     

                     

                    BRGDS

                     

                    /B

                    • 7. Re: "Crossing" jar boundaries in a ShrinkWrap WebArchive when using Weld
                      aslak

                      you can use resolveAs(ArchiveType) instead, that basically does your loop..

                       

                       

                      WebArchive aArchive = ShrinkWrap.create(WebArchive.class, "test-greeter.war")
                                .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml");
                                .addAsLibraries(DependencyResolvers.use(MavenDependencyResolver.class)
                                                                        .loadMetadataFromPom("pom.xml")
                                                                        .artifact("com.metria.arquillian:service")
                                                                        .resolveAs(JavaArchive.class));
                      
                      
                      • 8. Re: "Crossing" jar boundaries in a ShrinkWrap WebArchive when using Weld
                        bertil.karlsson

                        Ahh, point proven then I guess ("Better ways probably exists ...") ...

                         

                        Thanks!

                         

                        /B