95

I use maven to build a multi module project. My module 2 depends on Module 1 src at compile scope and module 1 tests in test scope.

Module 2 -

   <dependency>
       <groupId>blah</groupId>
       <artifactId>MODULE1</artifactId>
       <version>blah</version>
       <classifier>tests</classifier>
       <scope>test</scope>
   </dependency>

This works fine. Say my module 3 depends on Module1 src and tests at compile time.

Module 3 -

   <dependency>
       <groupId>blah</groupId>
       <artifactId>MODULE1</artifactId>
       <version>blah</version>
       <classifier>tests</classifier>
       <scope>compile</scope>
   </dependency>

When I run mvn clean install, my build runs till module 3, fails at module 3 as it couldn't resolve the module 1 test dependency. Then I do a mvn install on module 3 alone, go back and run mvn install on my parent pom to make it build. How can I fix this?

ROMANIA_engineer
  • 54,432
  • 29
  • 203
  • 199
user209947
  • 1,013
  • 1
  • 9
  • 5

2 Answers2

144

I have a doubt about what you are trying to do but but I'll assume you want to reuse the tests that you have created for a project (module1) in another. As explained in the note at the bottom of the Guide to using attached tests:

Note that previous editions of this guide suggested to use <classifier>tests</classifier> instead of <type>test-jar</type>. While this currently works for some cases, it does not properly work during a reactor build of the test JAR module and any consumer if a lifecycle phase prior to install is invoked. In such a scenario, Maven will not resolve the test JAR from the output of the reactor build but from the local/remote repository. Apparently, the JAR from the repositories could be outdated or completely missing, causing a build failure (cf. MNG-2045).

So, first, to package up compiled tests in a JAR and deploy them for general reuse, configure the maven-jar-plugin as follows:

<project>
  <build>
    <plugins>
     <plugin>
       <groupId>org.apache.maven.plugins</groupId>
       <artifactId>maven-jar-plugin</artifactId>
       <version>2.2</version>
       <executions>
         <execution>
           <goals>
             <goal>test-jar</goal>
           </goals>
         </execution>
       </executions>
     </plugin>
    </plugins>
  </build>
</project>

Then, install/deploy the test JAR artifact as usual (using mvn install or mvn deploy).

Finally, to use the test JAR, you should specify a dependency with a specified type of test-jar:

<project>
  ...
  <dependencies>
    <dependency>
      <groupId>com.myco.app</groupId>
      <artifactId>foo</artifactId>
      <version>1.0-SNAPSHOT</version>
      <type>test-jar</type>
      <scope>test</scope>
    </dependency>
  </dependencies>
  ...
</project>
Pascal Thivent
  • 562,542
  • 136
  • 1,062
  • 1,124
  • 4
    Pascal. First of all thanks a lot for answering all the maven questions !! Regarding this question. I have still a problem. I have some testBase class in one of my core modules that i want to use in all of the child objects. We have currenly the maven build in our CI. If i dont want to do any install of deploy to the test-jar and just to check out a fresh copy from trunk and run the mvn test. This fails , since i dont have the test-jar anywhere yet. Any idea how to deal with that ? – Roman Mar 28 '10 at 09:49
  • @Roman Running install is the "natural" way. But it looks like you found a workaround. – Pascal Thivent Mar 28 '10 at 13:30
  • It seems to be this issue 3559 not 2045 that is the hold up at this point: http://jira.codehaus.org/browse/MNG-3559 – Dave Aug 14 '13 at 16:31
  • Altough this explains what is happening it does not provide workaround. It just suggest to do what OP (and eg I) is already doing. – Antoniossss Jan 23 '20 at 09:52
  • Solution still works to this day, even with multi module maven projects – dehidehidehi Nov 24 '22 at 19:56
20

Regarding to my comment to Pascals question i think i have found a stuitable answer :

<plugins>
    <plugin>
        <artifactId>maven-jar-plugin</artifactId>
        <version>2.2</version>
        <executions>
            <execution>
            <goals>
                <goal>test-jar</goal>
            </goals>
            <phase>test-compile</phase>
        </execution>
        </executions>
        <configuration>
            <outputDirectory>${basedir}\target</outputDirectory>
        </configuration>
    </plugin>
</plugins>

The main difference here as you see here is the <phase> tag.

I will create the test-jar and it will be available in the compile phase of the tests and not only after the package phase.

Works for me.

Peter Hall
  • 53,120
  • 14
  • 139
  • 204
Roman
  • 7,933
  • 17
  • 56
  • 72
  • 1
    Yes, very convenient. Thanks for sharing. I guess the deploy approach is better only when you have a corporate directory (yes, I know this is strongly recommended). Thanks @Roman – Damien Dec 02 '10 at 21:04