3

I referred to this thread differences between dependencymanagement and dependencies in maven but this question is specific.

Parent POM:

<dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>com.company.rtdp.rtds</groupId>
      <artifactId>rtds-client</artifactId>
      <version>${rtdp.rtds-client.version}</version>
      <!-- SCENARIO 1 : Either give scope here in parent POM -->
      <!-- <scope>provided</scope> -->
    </dependency>
  </dependencies>
</dependencyManagement>

<rtdp.rtds-client.version>1.4.6</rtdp.rtds-client.version>

Child POM:

 <dependencies>
    <!-- SCENARIO 2
    <dependency> 
        <groupId>com.company.rtdp.rtds</groupId> 
        <artifactId>realtimedataserv-client</artifactId> 
        <version>1.4.6</version>
        <scope>provided</scope> 
    </dependency> 
    -->

    <dependency> 
        <groupId>com.company.idi</groupId> 
        <artifactId>idi-persistence</artifactId>
        <version>3.3</version>
        <!--  has a dependency of com.company.rtdp.rtds:rtds-client:jar:1.4.6:compile -->
    </dependency>
 </dependencies>

<!-- SCENARIO 1: OR give scope here in child POM 
<dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>com.company.rtdp.rtds</groupId>
      <artifactId>rtds-client</artifactId>
      <version>1.4.6</version>
      <scope>provided</scope> 
    </dependency>
  </dependencies>
</dependencyManagement>
-->

rtds-client is a transitive dependency of many artifacts out of which idi-persistence is one of them. I want to exclude 1.4.6 in all of the transitive dependencies since I am going to include a different artifact rtds-framework-client (different artifact name) explicitly which is backward compatible to 1.4.6 with <dependency> in child POM.

If have to use <exclusion> I have to explicitly give this in all the dependencies. So, I have decided to go <scope>provided</scope> way.

Known info of Maven based on which my question follows:

If I include the following in child POM (with a version higher than 1.4.6, then rtds-client in all transitive dependencies gets shifted to 1.8. I could see this from 'Dependency Hierarchy' of Eclipse which says 'omitted for conflict with 1.8' [compile]) which means it considers/overrides the version specified in child POM (idi-persistence now gets 1.8).

<dependency>
    <groupId>com.company.rtdp.rtds</groupId>
    <artifactId>rtds-client</artifactId>
    <version>1.8</version>
</dependency>

Question:

If I include the following in child POM without <dependencyManagement> around:

<dependency>
    <groupId>com.company.rtdp.rtds</groupId>
    <artifactId>rtds-client</artifactId>
    <version>1.4.6</version>
    <scope>provided<scope>
</dependency>

None of the rtds-client which comes as transitive dependency considers provided scope whereas I mention the same in a <dependencyManagement> tag either in parent or child POM, provided scope gets applied.

Why version gets affected but not scope given inside <dependency> tag and for scope (for this kind of use case) I have to go for <dependencyManagement> ?

Say if this is allowed, what problem it would lead us into ?

EDIT:

i) <scope>provided with <dependencyManagement>/<dependencies>/<dependency> either in child or parent POM:

enter image description here

Though the longer path is omitted, it says [provided],here.

[INFO] +- com.company.idi:idi-persistence:jar:3.3:compile
[INFO] |  +- com.company.rtdp.rtds:realtimedataserv-client:jar:1.4.6:provided

ii) <scope>provided with direct <dependencies>/<dependency> in child POM without <dependencyManagement> around :

enter image description here

Though the longer path is omitted, it does not say provided and just compile alone.

[INFO] --- maven-dependency-plugin:2.3:tree (default-cli) @ read-rest-service ---
[INFO] +- com.company.rtdp.rtds:realtimedataserv-client:jar:1.4.6:provided (scope not updated to compile)
user104309
  • 690
  • 9
  • 20
  • 1) It's called [``](https://maven.apache.org/pom.html#Exclusions) rather than ``. 2) Perhaps this is due to [_Dependency mediation_](http://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html#Dependency_Management): "_You can always guarantee a version by declaring it explicitly in your project's POM. Note that if two dependency versions are at the same depth in the dependency tree, [...] since Maven 2.0.9 it's the order in the declaration that counts: the first declaration wins._" – Gerold Broser Jul 08 '17 at 21:36
  • Question is not about resolution of version conflict. It is about scope conflict. Why does it not resolve the scope the same way it does version with ``? Say in the last snippet having version `1.4.6` `provided`, I replace the version to `1.8` retaining the same `scope`, rtds-client which comes as transitive dependencies for other dependencies in child pom, gets switched to version 1.8 (version conflict is taken care of), but it does not get switched to `provided` (it is still at `compile`)! It accepted a explicitly declared version but why not the scope? – user104309 Jul 08 '17 at 22:10
  • Potentially unnecessary info which might cause confusion but may be useful: I do not use rtds-client's classes directly in my project. So I don't have to explicitly declare that inside `` just to make it `provided` (if at all it worked) (looks like the purpose of explicit mention of dependency inside `` targets only version and its meant for dependencies whose classes must be directly used in our project) although even this sounds like a good solution to me. – user104309 Jul 08 '17 at 23:40
  • [continued] So it is better to mention `provided` inside `` either in child or parent pom to propagate everything inside of this tag if at all they are used down the hierarchy. But say I am using rtds-client classes inside my project, this approach sounds like a very valid solution. – user104309 Jul 08 '17 at 23:40
  • _Dependency mediation_ is not just about versions. That's just an example. It concerns whole dependencies and their declaration(s). The "_omitted for conflict with 1.8_" is because of this mediation since the doc also says in the previous sentence: "_Currently, Maven 2.0 only supports using the "nearest definition" which means that it will use the version of the closest dependency to your project in the tree of dependencies._". Without the complete POMs it's hard to say whether this behaviour (`provided` in `` vs. ``) is intended, hence, logical or whether it's possibly a bug. – Gerold Broser Jul 09 '17 at 10:24
  • And the transitive `1.4.6`s, in detail, don't get "_shifted_". They are ignored/omitted (as the msg says) and the `1.8`s are used instead – in accordance with _mediation_ – Gerold Broser Jul 09 '17 at 10:25
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/148722/discussion-between-user104309-and-gerold-broser). – user104309 Jul 09 '17 at 10:52
  • It's also `//` rather than just `/`. Is this even a real project with all these wrong declarations? – Gerold Broser Jul 09 '17 at 13:56
  • By `` I meant the whole hierarchy `//` and by `` I meant `/` without `` around. I will upload the hierarchy screenshots from eclipse. – user104309 Jul 09 '17 at 18:39
  • I know what you meant in your textual descriptions. I'm referring to your first POM excerpt which cannot work like that. – Gerold Broser Jul 09 '17 at 21:05
  • Yes. Simplification lead to mistake and confusion. – user104309 Jul 09 '17 at 21:07
  • I'm terribly sorry. With just fragments of information I can't help you further. If you think the POM is too big create a [mcve](https://stackoverflow.com/help/mcve). – Gerold Broser Jul 09 '17 at 23:17

1 Answers1

2

I can't comprehend your <scope>provided in <dependencyManagement> vs. <dependency.

If I declare a child POM, with no dependency[Management] in the parent whatsoever, like:

<project ...>
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>igb.so</groupId>
        <artifactId>SO-44987444-parent</artifactId>
        <relativePath>../SO-44987444-parent</relativePath>
        <version>0.0.1-SNAPSHOT</version>
    </parent>

    <artifactId>SO-44987444-child</artifactId>

    <dependencies>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-text</artifactId>
            <version>1.1</version>
            <!--  has a dependency of org.apache.commons:commons-lang3:jar:3.5:compile -->
        </dependency>
    </dependencies>

</project>

the dependency:tree looks like:

[INFO] ------------------------------------------------------------------------
[INFO] Building SO-44987444-child 0.0.1-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO] 
[INFO] --- maven-dependency-plugin:2.8:tree (default-cli) @ SO-44987444-child ---
[INFO] igb.so:SO-44987444-child:jar:0.0.1-SNAPSHOT
[INFO] \- org.apache.commons:commons-text:jar:1.1:compile
[INFO]    \- org.apache.commons:commons-lang3:jar:3.5:compile
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------

If I add commons-lang3 as direct dependency with <scope>provided:

        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.5</version>
            <scope>provided</scope>
        </dependency>

the dependency:tree looks like:

[INFO] ------------------------------------------------------------------------
[INFO] Building SO-44987444-child 0.0.1-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO] 
[INFO] --- maven-dependency-plugin:2.8:tree (default-cli) @ SO-44987444-child ---
[INFO] igb.so:SO-44987444-child:jar:0.0.1-SNAPSHOT
[INFO] +- org.apache.commons:commons-text:jar:1.1:compile
[INFO] \- org.apache.commons:commons-lang3:jar:3.5:provided
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------

Even if I add to the parent POM:

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.apache.commons</groupId>
                <artifactId>commons-lang3</artifactId>
                <version>3.5</version>
            </dependency>
        </dependencies>
    </dependencyManagement>

the dependency:tree results aren't any different.

Gerold Broser
  • 14,080
  • 5
  • 48
  • 107
  • Exactly. That is how I expected it to behave. But my dependency tree results with `dependency:tree` from eclipse (3.3.3 embedded) [ also from maven command line (3.5.0) ] and UI `Dependency Hierarchy` of Eclipse Mars.2 Release (4.5.2) do not match the pattern as yours. – user104309 Jul 09 '17 at 19:38
  • @user104309 As I mentioned in a comment to your question already, without the complete POMs it's hard to tell what's wrong. If you add them (parent plus one child) I can look further into it. – Gerold Broser Jul 09 '17 at 21:11
  • 1
    POM is too big. I have added more info to the POMs. Finally it looks like all the confusion is because of the way the UI `Dependency Hierarchy` in eclipse represents the dependency tree (not showing the `provided` mark on the omitted one for scenario 2 whereas it showed the `provided` mark on scenario 1 leading me to think that in scenario 2 rtds-client will be packaged during the build because `provided` scope did not apply to those omitted transitive dependencies) ? What does it mean `scope not updated to compile` ? What maven is trying to convey with that message? – user104309 Jul 09 '17 at 22:43