4 Replies Latest reply on Oct 7, 2013 4:39 AM by replicant77

    Wrong built WebArchive using Shrinkwrap Classpath resolution

    replicant77

      Hi,

       

      I have defined a simple war project and setup an arquillian test using shrinkwrap 2.0.0, that - as a test - just resolves the web archive via classpath resolution:

       

      @RunWith(Arquillian.class)
      public class ShrinkwrapTestIT {
          @Deployment
          public static Archive<?> createDeployment() {
              WebArchive war = Maven.resolver()
                      .resolve("shrinkwrap.test:shrinkwrap.test:war:0.0.1-SNAPSHOT").withClassPathResolution(true)
                      .withoutTransitivity().asSingle(WebArchive.class);
              System.out.println(war.toString(true));
              return war;
          }
      
          @Test
          public void test() {
              //do nothing
          }
      }
      
      
      

       

      The output shows, that the archive is incomplete (resource files are missing) and not even war conform:

      some_text_file.txt

      com/

      com/test/

      com/test/Test.class

       

      If i change the code to use .withClassPathResolution(false), the output is:

      /some_text_file.txt

      /index.jsp

      /com/

      /com/test/

      /com/test/Test.class

      /WEB-INF/

      /WEB-INF/web.xml

      /WEB-INF/sun-web.xml

      /META-INF/

      /META-INF/MANIFEST.MF

       

      Now the resources are included, but the class(es) are packaged at the top level and not under /WEB-INF/classes

       

      What am i doing wrong here? My pom looks like that:

       

      <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
          <modelVersion>4.0.0</modelVersion>
          <groupId>shrinkwrap.test</groupId>
          <artifactId>shrinkwrap.test</artifactId>
          <version>0.0.1-SNAPSHOT</version>
          <packaging>war</packaging>
      
          <properties>
              <project.build.sourceEncoding>ISO8859-1</project.build.sourceEncoding>
              <version.shrinkwrap.resolvers>2.0.0</version.shrinkwrap.resolvers>
          </properties>
      
          <dependencies>
              <!-- test dependencies -->
              <dependency>
                  <groupId>junit</groupId>
                  <artifactId>junit</artifactId>
                  <version>4.11</version>
              </dependency>
              <dependency>
                  <groupId>org.jboss.arquillian.junit</groupId>
                  <artifactId>arquillian-junit-container</artifactId>
                  <scope>test</scope>
              </dependency>
              <dependency>
                  <groupId>org.jboss.arquillian.container</groupId>
                  <artifactId>arquillian-glassfish-remote-3.1</artifactId>
                  <version>1.0.0.CR4</version>
                  <scope>test</scope>
              </dependency>
              <dependency>
                  <groupId>org.jboss.shrinkwrap.resolver</groupId>
                  <artifactId>shrinkwrap-resolver-depchain</artifactId>
                  <version>${version.shrinkwrap.resolvers}</version>
                  <scope>test</scope>
                  <type>pom</type>
              </dependency>
          </dependencies>
      
          <dependencyManagement>
              <dependencies>
                  <!-- Override dependency resolver with latest version. This must go *BEFORE*
                      the Arquillian BOM. -->
                  <dependency>
                      <groupId>org.jboss.shrinkwrap.resolver</groupId>
                      <artifactId>shrinkwrap-resolver-bom</artifactId>
                      <version>${version.shrinkwrap.resolvers}</version>
                      <scope>import</scope>
                      <type>pom</type>
                  </dependency>
                  <dependency>
                      <groupId>org.jboss.arquillian</groupId>
                      <artifactId>arquillian-bom</artifactId>
                      <version>1.1.1.Final</version>
                      <scope>import</scope>
                      <type>pom</type>
                  </dependency>
              </dependencies>
          </dependencyManagement>
      
          <build>
              <plugins>
                  <plugin>
                      <groupId>org.apache.maven.plugins</groupId>
                      <artifactId>maven-failsafe-plugin</artifactId>
                      <version>2.16</version>
                      <configuration>
                          <skipTests>${skipITs}</skipTests>
                      </configuration>
                      <executions>
                          <execution>
                              <goals>
                                  <goal>integration-test</goal>
                                  <goal>verify</goal>
                              </goals>
                          </execution>
                      </executions>
                  </plugin>
      
              </plugins>
          </build>
      </project>
      
      
      

       

      Many thanks,

      Gunther

        • 1. Re: Wrong built WebArchive using Shrinkwrap Classpath resolution
          kpiwko

          Hi Gunther,

           

          a WAR is actually never on java class path. So ShrinkWrap Resolver is guessing what on the classpath might represent the archive doing some file system and pom parsing magic. However, classpath resolution is used to get information about other projects in Maven Reactor, that is for multimodule projects. That said, you're resolving the project itself after package phase, which is pretty interesting idea. Can you please file a jira in ShrinkWrap Resolvers - JBoss Issue Tracker so it won't get lost?

           

          Meanwhile, I suggest you to look into MavenImporter, part of ShrinkWrap Resolver, which does exactly what you need:

           

          ShrinkWrap.create(MavenImporter.class).loadPomFromFile("pom.xml").importBuildOutput().as(WebArchive.class);
          
          

           

          (More details at: https://github.com/shrinkwrap/resolver)

           

          Thanks,

          Karel

          • 2. Re: Re: Wrong built WebArchive using Shrinkwrap Classpath resolution
            replicant77

            Hi Karel!

             

            Thanks for your answer! I will file a bug report.

             

            Your advise using MavenImporter is working, and - i think - it's fine if you are packaging and testing inside a standalone war project. But actually my war is part of a multi module ear project, with ejb modules, utility modules and the war module, in which i want to integration test. I want to make sure that i package an ear which incorporates the most recent classes/resources from my projects. Importing the ear or parts of it from the local maven repository (e.g. using .withClassPathResolution(false)) is impracticable, as we are in integration-test phase and import phase has not happened yet. One would have to execute the test twice in order to test against the most recent changes. So how do i do that? Are there any best practices for multi module projects? My initial approach was to assemble the ear manually through classpath resolving using something like:

            EnterpriseArchive ear = ShrinkWrap.create(EnterpriseArchive.class);
            //do that for all libs
            ear.addAsLibrary(Maven.resolver().loadPomFromFile("pom.xml").resolve("G:A:V").withoutTransitivity().asSingle(JavaArchive.class));
            //do that for all ejb and war modules
            ear.addAsModule(Maven.resolver().loadPomFromFile("pom.xml").resolve("G:A:V").withoutTransitivity().asSingle(JavaArchive.class));
            etc...

            That - though quite cumbersome and not very DRY conform - worked, except having the aforementioned malformed war archive.

             

            Could i instead perhaps use your approach, but instead point to the ear's pom? E.g.:

            ShrinkWrap.create(MavenImporter.class).loadPomFromFile("../my.ear.project/pom.xml").importBuildOutput().as(EnterpriseArchive.class); 

            Would that be viable and assemble the most recent ear?

             

            Thanks, Gunther

            • 3. Re: Re: Wrong built WebArchive using Shrinkwrap Classpath resolution
              kpiwko

              Hi Guther,

               

              I think that suggested approach would indeed be to use MavenImporter and point it to path of EAR's pom.xml. There is a big catch though, MavenImporter does not support EARs at this point, simply as MavenImporter mimics Maven behavior and nobody written support for EARs at this point [1].

               

              The classpath resolution approach should figure out there is a project already build by Maven when you are running in integration-test phase - that is the EAR you need is actually on the file system, which is you case. That's what your JIRA is about, I think.

               

              That said, if you want the same behavior in test phase, it is more complicated, as archive does not exists yet on filesystem. And in such case it is MavenImporter role again, although you would propagate information of what pom.xml to build not via path to file but via G:A:V. So, the best way would be to get support for EARs and than we could add G:A:V -> pom.xml "redirections" for classpath resolution and ensure the behavior is the same for "test" and "integration-test" phase. Because the main point of ShrinkWrap Resolvers project is to never rely that somebody pre-built something for you, if that's not available, build it on your own. That allows to avoid double rounds of execution you described above.

               

              One more hint, if you can ensure that somebody's built the EAR at the moment you run the tests, you can use ShrinkWrap ZipImporter - http://arquillian.org/guides/shrinkwrap_introduction/ . However, this will most likely break usage of your test from IDE, as IDE usually does not package the archive in the same location as Maven.

               

              Karel

               

              [1] [SHRINKRES-98] Add support of EAR in MavenImporter - JBoss Issue Tracker

              • 4. Re: Wrong built WebArchive using Shrinkwrap Classpath resolution
                replicant77