Alex Ciminian Alex Ciminian - 6 months ago 31
Java Question

How do I include a dependency's test jar into a Maven project's deployment?

I have two projects,

foo
and
foo-web
under the
com.example
group.
foo-web
depends on
foo
.

To be able to develop the UI part of the application without depending on external services, dummy DAOs were implemented in
foo
(they return static data so we don't have to connect to databases etc).

We were required to move the dummy classes to
src/test/java
. This means that they don't get deployed with
foo.jar
to the war built from the web project. I found these instructions on the maven site, but they don't seem to work for me.

In
foo
's
pom.xml
I have:

<plugin>
<artifactId>maven-jar-plugin</artifactId>
<executions>
<execution>
<id>test-jar</id>
<phase>test-compile</phase>
<goals>
<goal>test-jar</goal>
</goals>
</execution>
</executions>
</plugin>


When running
mvn install
on
foo-web
, in the target of
foo
I'd get two jars:
foo-1.0.0-SNAPSHOT.jar
and
foo-1.0.0-SNAPSHOT-tests.jar
. They both get installed fine in the local maven repository.

Before, the
foo-web
dependency looked like this:

<dependency>
<groupId>com.example</groupId>
<artifactId>foo</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>


And that would trigger the deployment of
foo-1.0.0-SNAPSHOT.jar
in the war. Now, I want to also deploy the
-tests
jar, preferably only for a "local" profile.

I tried in various ways to do this:

<profile>
<id>local</id>
<dependencies>
<dependency>
<groupId>com.example</groupId>
<artifactId>foo</artifactId>
<version>1.0.0-SNAPSHOT</version>
<type>test-jar</type>
</dependency>
</dependencies>
</profile>


This causes the source jar to be deployed with a different name:
com.example-foo.jar
and does not deploy the test jar. I also tried using
<classifier>
instead of
<type>
in the dependency, but it still does the same. I tried using the above dependency outside of the profile (alongside the others), but it still behaves the same.

If I add the
<type>
to the main dependency (without adding the other dependency) I get the test jar deployed (with the same name as above), but the source, naturally, does not get deployed.

The only difference from what's written in the documentation is the fact that the scope is not specified for the test dependency. Does it only work for the
test
scope? Can I somehow deploy the test classes differently.

I know the question's a bit convoluted, please let me know if there's something I can clarify.

Thanks!




Update:



I tried it in several more ways but it still won't work.

I added another execution to the maven-jar-plugin in the
foo
project (the dependency, not the main web project) in which I hoped to force maven to compile the test classes in the same jar as the main ones and reference the big bundle by a different classifier. I couldn't get it to work:

<execution>
<id>local-build</id>
<phase>package</phase>
<goals>
<goal>jar</goal>
</goals>
<configuration>
<classifier>batman</classifier>
<directory>${basedir}/src/test/java</directory> <!-- tried several variations here -->
<includes>
<include>**</include>
</includes>
</configuration>
</execution>


The jar was generated with the
batman
classifier, but I couldn't find any way to get it to include test classes in the
jar
goal.

Doing this, I realized that this does not depend on the
test-jar
type/
tests
classifier/
test
scope relationship. When I tried to specify the new jar I'm building besides the main one, I got the same behavior as when trying to include the
-tests
jar. I checked the local maven repository and both all jars from the dependent project are getting installed fine, so the problem is the main project's dependency resolution.

tl;dr



Everything boils down to the question if you can include the same dependency with multiple classifiers. From what I saw until now, the answer is no - I always get the
com.example-foo
jar when specifying the same dependency multiple times with different classifiers.

Answer

Better to configure maven pom file in your first module

<project>
    <groupId>com.example</groupId>
    <artifactId>foo</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <packaging>jar</packaging>
    <build>
        <plugins>
            ...
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <executions>
                    <execution>
                        <goals>
                            <goal>test-jar</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

After this a mvn install/release will also deploy an artifact foo-1.0.0-SNAPSHOT-tests.jar

Then configure the dependency on the test jar with classifier (like suggested in other responses)

<dependency>
    <groupId>com.example</groupId>
    <artifactId>foo</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <type>test-jar</type>
    <!-- uncomment if needed in test scope only
         <scope>test</scope>
    -->
</dependency>