Maven
  1. Maven
  2. MNG-4391

DependencyManagement should allow <replaceWith> to manage use of re-named, woven, instrumented or compatible artifacts

    Details

    • Type: Improvement Improvement
    • Status: Closed Closed
    • Priority: Major Major
    • Resolution: Incomplete
    • Affects Version/s: 2.2.1
    • Fix Version/s: None
    • Component/s: Dependencies
    • Labels:
      None
    • Complexity:
      Intermediate
    • Number of attachments :
      0

      Description

      [if only this was a later version of JIRA I'd have not lost all of what I just typed, as I could use Mylyn instead of the web UI. here goes again...]

      The challenge of using a different artifact instead of the one that is specified in a POM that you are consuming is not an easy one.

      Examples where this hits uses is:

      • the artifact name and packaging changes that Spring made at 2.5.6A (which was a big improvement)
      • wanting to use SLF4J instead of Apache commons logging (i.e. use something that provides the same API, but is an entirely different project)
      • wanting to use your own derivation of a public artifact
      • wanting to use a woven/instrumented version of a public artifact

      The current approach to replacing, say org.springframework : spring-beans with org.springframework : org.springframework.beans is to do ('scuse the shorthand):

      <dependencyManagement>
        <dependencies>
          <dependency>
            <groupId>com.sun.jersey.contribs</groupId>
            <artifactId>jersey-spring</artifactId>
            <exclusions> 
                 org.springframework : spring-beans
            </exclusions>
          </dependency>
          ... repeat for every artifact that uses spring-beans, and then add more if adding another artifact
        </dependencies>
      </dependencyManagement>
      

      to exclude it, and then globally include the replacement using:

      <dependencies>
        <dependency>
          <groupId>org.springframework</groupId>
          <artifactid>org.springframework.beans</groupId>
          <version>${spring.version}</version>
        </dependency>
      </dependencies>
      

      This is error prone, and could be made far easier by an extension to dependencies, which would remove the need to know what artifacts (jersey-spring in the above example) use the artifact that you are replacing. Here's how it would look:

      <dependencyManagement>
        <!-- this declares the version we want to use if this artifact is in use -->
        <dependencies>
          <dependency>
            <groupId>org.springframework</groupId>
            <artifactid>org.springframework.beans</groupId>
            <version>${spring.version}</version>
          </dependency>
      
          <!-- This deals with artifact name change -->
          <dependency>
            <groupId>org.springframework</groupId>
            <artifactid>spring-beans</groupId>
            <replaceWith>  <!-- list of dependency elements -->
                <dependency>
                  <groupId>org.springframework</groupId>
                  <artifactid>org.springframework.beans</groupId>
                </dependency>
                <!-- more dependency elements could be added here if an artifact has been split -->
            </replaceWith>
          </dependency>
      </dependencies>
      

      NOTE:

      • Nothing is specified in <dependencies> so no artifacts are globally added where they may not be needed. This means we can develop a project wide parent pom.xml.
      • Artifacts can have been split and merged
      • Derived artifacts, such as instrumented ones can easily be substituted, and could be selectively substituted using profiles.

        Activity

          People

          • Assignee:
            Unassigned
            Reporter:
            Neale
          • Votes:
            9 Vote for this issue
            Watchers:
            10 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: