What is the best way to declare a Maven dependency as only being used for the test runtime (but not test compilation) class path?
Specifically, I want slf4j-api
(a logging facade) as a typical, compile-scope dependency, but I want slf4j-simple
(the barebones implementation suitable for unit tests) only on the test runtime class path (it's not needed for test compilation). I've been doing this:
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<scope>test</scope>
</dependency>
However, the downside of this is that dependency:analyze
reports slf4j-simple
as unused, presumably because it's not needed for compilation:
[WARNING] Unused declared dependencies found:
[WARNING] org.slf4j:slf4j-simple:jar:1.7.7:test
I can't use a runtime
dependency because I don't want that dependency transitively inherited (e.g. so downstream dependencies can use log4j, etc. instead). I tried runtime
with optional=true
, but that results in the same warning.
(Note that I could also set ignoreNonCompile
for the dependency plugin, but that seems like a very blunt instrument that would hide other potential problems.)
There is no scope that does exactly what you want here; test
is the best available option.
A test-runtime
scope has been requested before (Re: Need for a test-runtime scope?) and the suggested workaround is exactly the ignoreNonCompile
configuration you've already discovered.
dependency:analyze
already has some limitations ("some cases are not detected (constants, annotations with source-only retention, links in javadoc)"). You may have to accept that any test
-scope dependencies that it warns against are false positives.
(You could split the definition of your tests into a separate module, which would have no slf4j
implementation dependencies, then run them in another module. I don't think that would be worth it.)