I have a Maven project which is used as a library in other projects. The setup is pretty standard: src/main
with the library code, src/test
with te
You can do this with the Maven Jar Plugin
Maven Jar Plugin
Since you're using Maven you can just cut a separate artifact of the project that contains the libraries you want to use in foo add the following plugin to create another jar artifact:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.3.2</version>
<executions>
<execution>
<goals>
<goal>test-jar</goal>
</goals>
</execution>
</executions>
</plugin>
This creates a second jar in this project of everything in the src/test directory.
Test Jars
You could splice out the stuff in that jar you don't need with some filters.
Then to use this library you would include this as a dependancy in foo:
<dependency>
<groupId>your.group</groupId>
<artifactId>parent-artifact-id</artifactId>
<version>1.0.0</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>
To separate the projects further you can also create a test only project with your more frameworky test jars.
See How to create a jar containing test classes (Preferred way) in the Maven Jar Plugin doc
Here is a POM fragment which splits the main JAR into the normal artifact and a "JUnit support JAR":
<build>
<plugins>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<executions>
<execution>
<id>default-jar</id>
<phase>package</phase>
<goals>
<goal>jar</goal>
</goals>
<configuration>
<archive>
<index>true</index>
<manifest>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
</manifest>
</archive>
<excludes>
<exclude>**/junit/**</exclude>
</excludes>
</configuration>
</execution>
<execution>
<id>junit-jar</id>
<phase>package</phase>
<goals>
<goal>jar</goal>
</goals>
<configuration>
<classifier>junit</classifier>
<archive>
<index>true</index>
<manifest>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
</manifest>
</archive>
<includes>
<include>**/junit/**</include>
</includes>
</configuration>
</execution>
<execution>
<id>test-jar</id>
<goals>
<goal>test-jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
In a nutshell, it looks for any package with junit
in its name and puts it into the JUnit JAR, excluding it from the normal artifact.
If the coordinate for the normal jar is
<groupId>com.group</groupId>
<artifactId>foo</artifactId>
then you can get the JUnit support code by simply adding <classifier>junit</classifier>
:
<groupId>com.group</groupId>
<artifactId>foo</artifactId>
<classifier>junit</classifier>
So to use this, the POM which depends on com.group:foo
will look like this:
<dependency>
<groupId>com.group</groupId>
<artifactId>foo</artifactId>
<version>...</version>
</dependency>
<dependency>
<groupId>com.group</groupId>
<artifactId>foo</artifactId>
<version>...</version>
<classifier>junit</classifier>
<scope>test</scope>
</dependency>
Sometimes, you will need JUnit to compile your "JUnit support JAR". If that's the case, use
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>compile</scope>
<optional>true</optional>
</dependency>
to include JUnit into the build. This will make the dependency available at compile time but it will not leak to anyone else.