ChatGPT解决这个技术问题 Extra ChatGPT

Correct way to declare multiple scope for Maven dependency?

I have a dependency that I want to use in test scope (so that it is in the classpath when I am running unit tests), and in runtime scope (so that I can contain that in WAR/EAR/other packaging for deployment, but not affecting transitive dependency lookup for dependent artifacts).

A real life example is SLF4J's implementation JARs (e.g. Logback). I want it to exist in the classpath when I am running tests, and I want it to be included in my WAR/EAR, but I don't want project depending on my project to include that in transitive dependency lookup.

I tried to use <scope>test,runtime</scope> but Maven 3 produces a warning:

[WARNING] 'dependencies.dependency.scope' for org.slf4j:jcl-over-slf4j:jar 
must be one of [provided, compile, runtime, test, system] but is 'test,runtime'. 

What is the right way for declaring the dependency scope in such a case?

It's stupid. How am I supposed to use Guava in my tests? @VisibleForTesting is useful for me

C
Christopher

The runtime scope also makes the artifact available on the test classpath. Just use runtime. (See the Maven documentation.)

To avoid having the dependency resolved transitively, also make it optional with <optional>true</optional>:

<dependency>
  <groupId>ch.qos.logback</groupId>
  <artifactId>logback</artifactId>
  <version>0.5</version>
  <scope>runtime</scope>
  <optional>true</optional>
</dependency>

However, the artifact is not available when compiling the test sources, which I believe is what he requires. At least, that's what I'm trying to figure out. I want it available for test for compilation and running, but not available for the main artifact during compilation (intentionally).
@voor I do not think you are correct. Runtime-scoped artifacts should also be available when compiling test sources. If that is not the case, I'd consider that a bug in Maven.
@Christopher From my experiments, it looks like voor is right: I get compilation errors in my tests when I use the runtime scope.
@jplandrain That sounds like a bug, and it goes against the documented/intended behavior. I would recommend you file an issue at issues.apache.org/jira/browse/MNG and demonstrate the problem with an example project, for it to be fixed.
@mwKART import and runtime scope makes no sense. import scope is not a true scope. It's just special syntax to include a dependencyManagement section declared in a separate POM file for easy reuse. I would advise that this is the only scope which would be appropriate to declare in a dependencyManagement section. Your actual scope (runtime, for example) should be declared in the dependencies section when you use it.
c
carlspring

You can only define one scope value per <scope/> tag.

I'm afraid what you'd like to do cannot be achieved by merely using a scope. If you define a scope of test, it will only be available during tests; if you define a scope of provided, that would mean that you would expect that dependency for your project to be resolved and used during both compilation and tests, but it will not be included in your WAR file. Either way, it's not what you would want.

Therefore, I would recommend you have a look at the maven-assembly-plugin, with which you can achieve it, but it will still require some playing around.


B
Buhake Sindi

Declaring a dependency with a scope of runtime ensures that the library is not available during compile time.

Declaring the dependency as optional causes a break in the dependency resolution process; projects depending on your libraries will need to explicitly include the dependencies themselves.

So the correct way to declare this would be:

<dependency>
  <groupId>org.slf4j</groupId>
  <artifactId>jcl-over-slf4j</artifactId>
  <version>1.7.13</version>
  <scope>runtime</scope>
  <optional>true</optional>
</dependency>

P
Preeti Joshi

Not sure if this would still help someone who is still looking for a simple way to do this - https://howtodoinjava.com/maven/maven-dependency-scopes/ this link helped me add the correct scope. Here is the summary of mapping of scopes and the phases where we need the dependencies.

compile - build, test and run provided - build and test runtime - test and run test - compile and test

So, when I needed the dependency during test and runtime, I gave the scope as "runtime" and it worked as expected.