You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@maven.apache.org by "Hari Krishna Dara (Jira)" <ji...@apache.org> on 2021/12/19 14:38:00 UTC

[jira] [Updated] (MNG-7368) Merge depencyManagement/dependencies instead of overwriting

     [ https://issues.apache.org/jira/browse/MNG-7368?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Hari Krishna Dara updated MNG-7368:
-----------------------------------
    Description: 
When inheriting {{dependencyManagement}} from parent, Maven's current merge logic is at the level of the list of {{dependencies}} which involves choosing the entire child's {{dependency}} definition over that of the parent, i.e., no merging actually happens at the {{dependency}} level (it is all or nothing). This essentially makes it impossible to incrementally build the {{dependencyManagement}}. If the child projects have to repeat the entire {{dependency}} definition, it defeats the purpose of sharing them in a parent-pom across multiple related projects. E.g., one common reason for managing them in parent is to centralize {{version}} for all dependencies at one place, but if the child must repeat the {{version}} to change anything in that dependency such as {{scope}} or {{exclusion}} rules, then there is no longer one central place.

I am attaching a very basic project structure (also attached as {{depman-inheritance.zip}}) to better demonstrate the issue.

Parent POM with a couple of dependencies:

{code:xml|title=parent/pom.xml}
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>depman-inheritance</groupId>
  <artifactId>parent</artifactId>
  <version>1.0-SNAPSHOT</version>
  <name>parent</name>
  <packaging>pom</packaging>

  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.11</version>
        <scope>test</scope>
      </dependency>
      <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-text</artifactId>
        <version>1.9</version>
      </dependency>
    </dependencies>
  </dependencyManagement>
</project>
{code}

Project Root POM trying to change just the scope of one of the dependencies:

{code:xml|title=project/pom.xml}
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>depman-inheritance</groupId>
    <artifactId>parent</artifactId>
    <version>1.0-SNAPSHOT</version>
    <relativePath>../parent/pom.xml</relativePath>
  </parent>

  <groupId>depman-inheritance</groupId>
  <artifactId>project</artifactId>
  <version>1.0-SNAPSHOT</version>
  <name>project</name>
  <packaging>pom</packaging>

  <modules>
    <module>module</module>
  </modules>

  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
	<scope>compile</scope>
      </dependency>
    </dependencies>
  </dependencyManagement>
</project>
{code}

Module POM simply using the dependencies:

{code:xml|title=project/module/pom.xml}
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>depman-inheritance</groupId>
    <artifactId>project</artifactId>
    <version>1.0-SNAPSHOT</version>
  </parent>

  <groupId>depman-inheritance</groupId>
  <artifactId>module</artifactId>
  <version>1.0-SNAPSHOT</version>
  <name>module1</name>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
    </dependency>
    <dependency>
      <groupId>org.apache.commons</groupId>
      <artifactId>commons-text</artifactId>
    </dependency>
  </dependencies>
</project>
{code}

With this, if we run any maven command in the project, I get the below error:

{noformat}
$ mvn dependency:tree
...
[ERROR] [ERROR] Some problems were encountered while processing the POMs:
[ERROR] 'dependencies.dependency.version' for junit:junit:jar is missing. @ line 17, column 17
 @
[ERROR] The build could not read 1 project -> [Help 1]
[ERROR]
[ERROR]   The project depman-inheritance:module:1.0-SNAPSHOT (/Users/hdara/git/hdara/playground-mvn-project/depman-inheritance/project/module/pom.xml) has 1 error
[ERROR]     'dependencies.dependency.version' for junit:junit:jar is missing. @ line 17, column 17
...
{noformat}

I would like to propose that the support for deeper merging be added to Maven. There are however two aspects of this merging that I am not sure:
- Should/Can it be applied to all non-key fields?
- How to handle exclusion rules? Should they be overriding or be additive?

  was:
When inheriting {{dependencyManagement}} from parent, Maven's current merge logic is at the level of the list of {{dependencies}} which involves choosing the entire child's {{dependency}} definition over that of the parent, i.e., no merging actually happens at the {{dependency}} level (it is all or nothing). This essentially makes it impossible to incrementally build the {{dependencyManagement}}. If the child projects have to repeat the entire {{dependency}} definition, it defeats the purpose of sharing them in a parent-pom across multiple related projects. E.g., one common reason for managing them in parent is to centralize {{version}} for all dependencies at one place, but if the child must repeat the {{version}} to change anything in that dependency such as {{scope}} or {{exclusion}} rules, then there is no longer one central place.

I am attaching a very basic project structure (also attached as {{depman-inheritance.zip}}) to better demonstrate the issue.

Parent POM with a couple of dependencies:

{code:xml|title=parent/pom.xml}
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>depman-inheritance</groupId>
  <artifactId>parent</artifactId>
  <version>1.0-SNAPSHOT</version>
  <name>parent</name>
  <packaging>pom</packaging>

  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.11</version>
        <scope>test</scope>
      </dependency>
      <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-text</artifactId>
        <version>1.9</version>
      </dependency>
    </dependencies>
  </dependencyManagement>
</project>
{code}

Project Root POM trying to change just the scope of one of the dependencies:

{code:xml|title=project/pom.xml}
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>depman-inheritance</groupId>
    <artifactId>parent</artifactId>
    <version>1.0-SNAPSHOT</version>
    <relativePath>../parent/pom.xml</relativePath>
  </parent>

  <groupId>depman-inheritance</groupId>
  <artifactId>project</artifactId>
  <version>1.0-SNAPSHOT</version>
  <name>project</name>
  <packaging>pom</packaging>

  <modules>
    <module>module</module>
  </modules>

  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
	<scope>compile</scope>
      </dependency>
    </dependencies>
  </dependencyManagement>
</project>
{code}

Module POM simply using the dependencies:

{code:xml|title=project/module/pom.xml}
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>depman-inheritance</groupId>
    <artifactId>project</artifactId>
    <version>1.0-SNAPSHOT</version>
  </parent>

  <groupId>depman-inheritance</groupId>
  <artifactId>module</artifactId>
  <version>1.0-SNAPSHOT</version>
  <name>module1</name>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
    </dependency>
    <dependency>
      <groupId>org.apache.commons</groupId>
      <artifactId>commons-text</artifactId>
    </dependency>
  </dependencies>
</project>
{code}

With this, if we run any maven command in the project, I get the below error:

{code}
$ mvn dependency:tree
...
[ERROR] [ERROR] Some problems were encountered while processing the POMs:
[ERROR] 'dependencies.dependency.version' for junit:junit:jar is missing. @ line 17, column 17
 @
[ERROR] The build could not read 1 project -> [Help 1]
[ERROR]
[ERROR]   The project depman-inheritance:module:1.0-SNAPSHOT (/Users/hdara/git/hdara/playground-mvn-project/depman-inheritance/project/module/pom.xml) has 1 error
[ERROR]     'dependencies.dependency.version' for junit:junit:jar is missing. @ line 17, column 17
...
{code}

I would like to propose that the support for deeper merging be added to Maven. There are however two aspects of this merging that I am not sure:
- Should/Can it be applied to all non-key fields?
- How to handle exclusion rules? Should they be overriding or be additive?


> Merge depencyManagement/dependencies instead of overwriting
> -----------------------------------------------------------
>
>                 Key: MNG-7368
>                 URL: https://issues.apache.org/jira/browse/MNG-7368
>             Project: Maven
>          Issue Type: Improvement
>          Components: Inheritance and Interpolation
>    Affects Versions: 3.8.1
>            Reporter: Hari Krishna Dara
>            Priority: Major
>              Labels: dependencies, dependency
>         Attachments: depman-inheritance-1.zip
>
>
> When inheriting {{dependencyManagement}} from parent, Maven's current merge logic is at the level of the list of {{dependencies}} which involves choosing the entire child's {{dependency}} definition over that of the parent, i.e., no merging actually happens at the {{dependency}} level (it is all or nothing). This essentially makes it impossible to incrementally build the {{dependencyManagement}}. If the child projects have to repeat the entire {{dependency}} definition, it defeats the purpose of sharing them in a parent-pom across multiple related projects. E.g., one common reason for managing them in parent is to centralize {{version}} for all dependencies at one place, but if the child must repeat the {{version}} to change anything in that dependency such as {{scope}} or {{exclusion}} rules, then there is no longer one central place.
> I am attaching a very basic project structure (also attached as {{depman-inheritance.zip}}) to better demonstrate the issue.
> Parent POM with a couple of dependencies:
> {code:xml|title=parent/pom.xml}
> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
>   <modelVersion>4.0.0</modelVersion>
>   <groupId>depman-inheritance</groupId>
>   <artifactId>parent</artifactId>
>   <version>1.0-SNAPSHOT</version>
>   <name>parent</name>
>   <packaging>pom</packaging>
>   <dependencyManagement>
>     <dependencies>
>       <dependency>
>         <groupId>junit</groupId>
>         <artifactId>junit</artifactId>
>         <version>4.11</version>
>         <scope>test</scope>
>       </dependency>
>       <dependency>
>         <groupId>org.apache.commons</groupId>
>         <artifactId>commons-text</artifactId>
>         <version>1.9</version>
>       </dependency>
>     </dependencies>
>   </dependencyManagement>
> </project>
> {code}
> Project Root POM trying to change just the scope of one of the dependencies:
> {code:xml|title=project/pom.xml}
> <?xml version="1.0" encoding="UTF-8"?>
> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
>   <modelVersion>4.0.0</modelVersion>
>   <parent>
>     <groupId>depman-inheritance</groupId>
>     <artifactId>parent</artifactId>
>     <version>1.0-SNAPSHOT</version>
>     <relativePath>../parent/pom.xml</relativePath>
>   </parent>
>   <groupId>depman-inheritance</groupId>
>   <artifactId>project</artifactId>
>   <version>1.0-SNAPSHOT</version>
>   <name>project</name>
>   <packaging>pom</packaging>
>   <modules>
>     <module>module</module>
>   </modules>
>   <dependencyManagement>
>     <dependencies>
>       <dependency>
>         <groupId>junit</groupId>
>         <artifactId>junit</artifactId>
> 	<scope>compile</scope>
>       </dependency>
>     </dependencies>
>   </dependencyManagement>
> </project>
> {code}
> Module POM simply using the dependencies:
> {code:xml|title=project/module/pom.xml}
> <?xml version="1.0" encoding="UTF-8"?>
> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
>   <modelVersion>4.0.0</modelVersion>
>   <parent>
>     <groupId>depman-inheritance</groupId>
>     <artifactId>project</artifactId>
>     <version>1.0-SNAPSHOT</version>
>   </parent>
>   <groupId>depman-inheritance</groupId>
>   <artifactId>module</artifactId>
>   <version>1.0-SNAPSHOT</version>
>   <name>module1</name>
>   <dependencies>
>     <dependency>
>       <groupId>junit</groupId>
>       <artifactId>junit</artifactId>
>     </dependency>
>     <dependency>
>       <groupId>org.apache.commons</groupId>
>       <artifactId>commons-text</artifactId>
>     </dependency>
>   </dependencies>
> </project>
> {code}
> With this, if we run any maven command in the project, I get the below error:
> {noformat}
> $ mvn dependency:tree
> ...
> [ERROR] [ERROR] Some problems were encountered while processing the POMs:
> [ERROR] 'dependencies.dependency.version' for junit:junit:jar is missing. @ line 17, column 17
>  @
> [ERROR] The build could not read 1 project -> [Help 1]
> [ERROR]
> [ERROR]   The project depman-inheritance:module:1.0-SNAPSHOT (/Users/hdara/git/hdara/playground-mvn-project/depman-inheritance/project/module/pom.xml) has 1 error
> [ERROR]     'dependencies.dependency.version' for junit:junit:jar is missing. @ line 17, column 17
> ...
> {noformat}
> I would like to propose that the support for deeper merging be added to Maven. There are however two aspects of this merging that I am not sure:
> - Should/Can it be applied to all non-key fields?
> - How to handle exclusion rules? Should they be overriding or be additive?



--
This message was sent by Atlassian Jira
(v8.20.1#820001)