38

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.)

Trevor Robinson
  • 15,694
  • 5
  • 73
  • 72
  • what is this is required at runtime for main source ? won't it still complain for `runtime` scoped dependency ? – jmj Dec 31 '14 at 22:19
  • In general transitive dependencies need not be declared. For an optional dependency (typically like logging which can use different frameworks) your procedure is right. Maybe you can add a scope test too. – Joop Eggen Dec 31 '14 at 22:33
  • 1
    It does also complain (wrongly, IMHO) for a `runtime` dependency, so it seems like scope alone is not the answer here. What I really want is a scope that is the intersection of `test` and `runtime` (as far as the class path) and for the dependency plugin to act less dumb about "unused" `runtime` dependencies. – Trevor Robinson Dec 31 '14 at 22:35
  • Another use case I’m coming across right now is when you want to avoid having JUnit 4 in your test classpath when compiling the tests, but you still need it to run the tests, e.g. when using Testcontainers’ `RabbitMQContainer` or `ElasticsearchContainer` (which both implement `TestRule` for some reason) ([Testcontainers’ issue](https://github.com/testcontainers/testcontainers-java/issues/970) in case you are interested) – Didier L Apr 20 '22 at 12:19

4 Answers4

23

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.)

Joe
  • 29,416
  • 12
  • 68
  • 88
  • 2
    For the javadoc issue I have resorted to linking to the fully qualified class name and adding the base link url to the javadoc plugin and not declaring a dependency on the project. This avoids having an import statement and other potential negative issues of having a dependency listed which is not actually required. – Brett Okken Jan 01 '15 at 17:19
  • 2
    Issue introduced [here](https://issues.apache.org/jira/browse/MNG-6545). – Olivier Cailloux Dec 29 '18 at 10:40
5

There is no concept of test-runtime in maven. The only real downside is the dependency analysis identifying these runtime test dependencies as unused. Since they are only test dependencies, however, this is pretty benign and cannot cause issues to other projects transitively dependent on this project.

Brett Okken
  • 6,210
  • 1
  • 19
  • 25
4

Since maven-dependency-plugin 2.10 (revision 1649454, Jan 2015), you can also add to the configuration a list of ignoredDependencies, ignoredUnusedDeclaredDependencies and ignoredUsedUndeclaredDependencies.

Trevor Robinson
  • 15,694
  • 5
  • 73
  • 72
0

As a workaround i would suggest to have separate maven project with test cases that depend on main project

jnr
  • 790
  • 1
  • 7
  • 9