83

Dependencies decorated by <optional>true</optional> or <scope>provided</scope> will be ignored when they are dependent transitively. I have read this, and my understanding is like the difference between @Component and @Service in Spring, they only vary semantically.

Is it right?

Toni
  • 3,296
  • 2
  • 13
  • 34
qining.shi
  • 845
  • 1
  • 6
  • 4
  • I have been suspecting (but have not proved it :P ) the main difference is, `optional` will still involve in transitive dependency resolution while `provided` will not. For example, u have `A` depends on `B` and optionally on `C:1.0`, `B` (not optionally) depends on `C:2.0`, the result will be `A` is having non-optional dependency (coz transitively from `B`), with version `1.0` (coz `C:1.0` is closest). Just my guess but not proved, you may have a try – Adrian Shum Nov 03 '16 at 04:22
  • I read the 2 answers present at the time and still fail to see the distinction b/w the two. So is it just a semantic difference or the behavior varies to? – YetAnotherBot Nov 26 '18 at 06:36
  • 3
    Some remark: spring-boot-maven-plugin doesn't exclude neither provider no optional dependencies from packaging. See [Exclusion of scope or artifact for spring-boot-maven-plugin](https://github.com/spring-projects/spring-boot/issues/674) – Grigory Kislin Feb 02 '19 at 11:28

2 Answers2

73

In addition to the comment, there is more important semantic difference: "Provided" dependencies are expected to be supplied by the container, so if your container gives you hibernate, you should mark hibernate as provided.

Optional dependencies are mainly used to reduce the transitive burden of some libraries. For example: If you can use a library with 5 different database types, but you usually only require one, you can mark the library-dependent dependencies as optional, so that the user can supply the one they actually use. If you don't do, you might get two types of problems:

  1. The library pulls a huge load of transitive dependencies of which you actually need very few so that you blow up your project without reason.

  2. More dangerously: You might pull two libraries with overlapping classes, so that the class loader cannot load both of them. This might lead to unexpected behaviour of your library.

Felix
  • 5,804
  • 4
  • 25
  • 37
J Fabian Meier
  • 33,516
  • 10
  • 64
  • 142
  • I agree All but the Problem Two. In my opinion, One dependency will be imported only one version in One Project. So it never exists that one library is overlapped by another. – qining.shi Nov 04 '16 at 02:48
  • 7
    Your comment is only true if the two artifacts share the same groupId and artifactId. If you have different groupId or different artifactId, but the same classes, Maven will not find that mistake. – J Fabian Meier Nov 07 '16 at 09:12
  • 1
    thank you very much. I have understood it now. it exists possibly that some classes have the same ClassName and NameSpace. But ClassLoder only load once for one class. so it is unpredictable which Class is loaded. I should learn about ClassLoader. – qining.shi Nov 08 '16 at 03:41
  • or you could try https://github.com/basepom/duplicate-finder-maven-plugin – Jakub Bochenski Jul 05 '18 at 14:32
  • @JFabianMeier what if, even in second case, we mark the scope as provided and wait for the user to add the dependency as he/she needs? Is it necessarily the container to provide dependency in case of "provided" scope or the parent project can also provide it ? If parent can also provide the needed dependency then how "optional" tag is any different from provided scope ? – ASHISH KARN Feb 01 '23 at 14:51
  • 1
    @ASHISHKARN With "parent" of x you probably don't mean the parent POM, but a project that uses x as dependency? Sure you can also add the dependency again in `compile` scope and override the `provided` scope. But, as I tried to say, the difference is mainly **semantic**, i.e. you signal the user that this dependency should come from the container, while for optional dependencies, you signal that you need to explicitly add the necessary dependencies. – J Fabian Meier Feb 01 '23 at 18:23
7

A minor difference I'd like to point out is the treatment of optional vs. provided by various plugins that create packages.

Apparently war plugin will not package optional dependencies, but there is an open bug about it: https://issues.apache.org/jira/browse/MWAR-351

The assembly plugin doesn't seem to provide any way to filter based on optional status, while it allows you to filter based on scope.

It seems the same is true for the shade plugin.

TL;DR if you are not developing a library, but a top-level application provided scope will give you more flexibility.

Jakub Bochenski
  • 3,113
  • 4
  • 33
  • 61