Question

I have a multi-module project built with maven. I need to run the project's integration tests daily. It is not possible to do this during the standard maven build cycle, because on runtime the integration tests defined within the modules have circular dependencies, which are illegal for me to declare on their poms.

Instead, I have created a separate project named Global that lists all modules jars and test-jars as its dependencies. Global has the same parent as all the modules. The idea is that using maven-ant-tasks I will be able to get a classpath of all modules jars and test-jars and go on from there. Global's pom.xml dependency section is as follows:

<dependency>
    <groupId>mygroup</groupId>
    <artifactId>A</artifactId>
    <version>${project.version}</version>
</dependency>
<dependency>
    <groupId>mygroup</groupId>
    <artifactId>A</artifactId>
    <version>${project.version}</version>
    <type>test-jar</type>
    <scope>test</scope>
</dependency>

<dependency>
    <groupId>mygroup</groupId>
    <artifactId>B</artifactId>
    <version>${project.version}</version>
</dependency>
<dependency>
    <groupId>mygroup</groupId>
    <artifactId>B</artifactId>
    <version>${project.version}</version>
    <type>test-jar</type>
    <scope>test</scope>
</dependency>

...etc

The problem is that I cannot seem to get a classpath that contains all jars and test-jars declared on Global's pom.xml (and their runtime dependencies) using the ant tasks available. I have tried (among other things):

<dependencies pathId="cp1" type="jar" usescope="runtime">
    <pom file="${basedir}/pom.xml">
        <profile id="DEV" />
    </pom>
</dependencies>

[1] This one fetches all runtime dependencies. Nothing wrong with that.

<dependencies pathId="cp2">
    <dependency groupId="mygroup" artifactId="Global" version="myVersion" scope="test" type="test-jar"/>
</dependencies>

[2] This one fetches all runtime dependencies along with Global-myversion-tests.jar, but no other test-jar.

<dependencies pathId="cp3" type="test-jar" usescope="test">
    <pom file="${basedir}/pom.xml">
        <profile id="DEV" />
    </pom>
</dependencies>

[3] This one fetches nothing.

Obviously, declaring something like [2] once for each module will do the trick, but I am looking to create a setup that will not need to edit a gazillion files each time a new module is added or removed. BTW I am using maven-ant-task-2.1.3.

Thanks for any input.

---Edits for @yannisf accepted answer---

You should not ever have cyclic dependencies

I assume you mean for maven builds. Having cyclic dependencies on runtime is pretty common, for example:

Module A declares interface: UploadToDocumentManagementSystem

Module B implements it in : UploadToCoolDms (that way in the future, when the DMS system changes to CoolerDms module B can be replaced by a new implementation with no side-effects to the rest of the app).

Module B depends on A compile time (and, by definition, runtime as well)

Module A depends on B on runtime

Maven does not allow to declare this. The reason, that I can sympathize with, is that maven needs to complete build cycles (including tests) of multi-module projects in a specific order. Thing is, it is not really necessary to declare it if you get rid of any runtime dependecy to B for the tests of A (which is good practice and should happen anyway).

You should do things the maven way instead of resorting to ant-tasks

Fair enough, I can see how maven-ant-tasks was not made for this use.

In your global pom you are declaring dual types for the same artifact (jar, test-jar)

Is that a problem in general? For example module A contains some samples for its tests that I would like to use in the tests of module B as well. Is it wrong (by maven best practices standards) to declare that B depends on A jar (compile scope) and on A test-jar (test scope)? Won't an integration tests project justify to depend on a module as well as the same module's samples and resources used for its unit tests?

tl;dr version: I will attempt to rearrange the tests declared on the modules and create separate module(s) for integration tests (assuming I can get 20 developers to play ball). Thanks for the answer and for making me admit defeat and stop trying to make maven work with the project instead of making the project work with maven :).

Was it helpful?

Solution

You are trying to break the maven conventions in many ways. 1. You should not ever have cyclic dependencies, 2. You should do things the maven way instead of resorting to ant-tasks 3. In your global pom you are declaring dual types for the same artifact (jar, test-jar).

Although at first this might not seem to answer your question, you should take a step back and rethink your layout. Integration tests need all the dependencies and are much more demanding than unit tests. So, instead of trying to fit them into the existing projects, create a separate maven project in the same group, that will only host integration tests (under src/java/test, main will be blank) and will have as dependencies all the other projects.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top