Hello everybody.
I was very exited to discover that the latest Gradle version comes with a new Java test fixtures plugin.
I daily work on multi-project code bases. I previously created my own test fixtures source set but I certainly did not do it as well as this new plugin does.
I replaced my custom configuration by this new plugin and it globally worked very well and I would like to thank everybody that worked on it!
I just encountered an issue when using this plugin on projects that are published on Maven.
We have a set of libraries shared by multiple code bases. It is a multi-project build and each project is published as a Maven artifact in a Maven repository. To simplify, let’s say it contains two projects, shared-project-1
and shared-project-2
. shared-project-2
depends on shared-project-1
(implementation
dependency type).
In another code base, we have a dependency to shared-module-2
that is resolved via our internal Maven repository.
This worked as expected until I apply the Java test fixtures plugin to the shared projects. The project builds (the dependency to shared-project-2
is correctly resolved) but it fails at runtime because a class of the shared-project-1
cannot be resolved. After investigation, it appears that the classpath used at runtime or when running tests (same issue) does contain the shared-module-2
jar but neither the shared-module-1
jar nor its own dependencies.
When I don’t apply the Java test fixtures plugin to the shared build, the Maven pom of shared-project-2
simply contains a dependency to share-project-1
in runtime
scope.
When I apply the plugin (which automatically publishes test fixtures with the test-fixtures
classifier), the dependencies are a little more complex. It still contains the dependency to shared-project-1
in runtime
scope, but it also contains an optional
dependency to shared-project-1
in compile
scope. I assume this second dependency is about the test-fixtures
jar.
It sounds like when this optional dependency exists, it overrides the other ones defined to this same artifact and Gradle excludes it from the runtime scope (even if the dependency is explicitly declared to this artifact in scope runtime
).
I tried to replace the dependency between shared-project-2
and shared-project-1
by an api
one (even if I don’t need it). In this case, the pom contains two dependencies to the shared-module-1
, one in compile
scope and one optional
in compile
scope, but the result is the same.
Note that I don’t get this issue when skipping the Maven repository publication thanks to includeBuild
. It probably confirms that the problem comes from the fact this artifact is published in a Maven repository (given that the Maven dependency model is less rich than the Gradle one ?).
I don’t know how to fix this issue. Is the published Maven pom correct? Is the Gradle behavior regarding optional
dependencies right ? I don’t know enough the Maven model to answer these questions.
Can anyone help me?
Thanks in advance!