Maven
  1. Maven
  2. MNG-3380

MavenMetadataSource retrieves ResolutionGroup without consulting ManagedVersionMap, is problem when relocation

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 2.0.8
    • Fix Version/s: 2.0.10, 2.1.0-M1
    • Component/s: Dependencies
    • Labels:
      None
    • Flags:
      Patch

      Description

      Consider the following scenario:

      <project>
        <modelVersion>4.0.0</modelVersion>
        <groupId>root-groupId</groupId>
        <artifactId>root-artifactId</artifactId>
        <version>1</version>
        <dependencies>
          <dependency>
            <groupId>direct-dependency-groupId</groupId>
            <artifactId>direct-dependency-artifactId</artifactId>
            <version>1</version>
          </dependency>
        </dependencies>
        <dependencyManagement>
          <dependencies>
            <dependency>
              <groupId>transitive-dependency-new-groupId</groupId>
              <artifactId>transitive-dependency-artifactId</artifactId>
              <version>2</version>
            </dependency>
          </dependencies>
        </dependencyManagement>
      </project>
      
      <project>
        <modelVersion>4.0.0</modelVersion>
        <groupId>direct-dependency-groupId</groupId>
        <artifactId>direct-dependency-artifactId</artifactId>
        <version>1</version>
        <dependencies>
          <dependency>
            <groupId>transitive-dependency-old-groupId</groupId>
            <artifactId>transitive-dependency-artifactId</artifactId>
            <version>1</version>
          </dependency>
        </dependencies>
      </project>       
      
             
      <project>
        <modelVersion>4.0.0</modelVersion>
        <groupId>transitive-dependency-old-groupId</groupId>
        <artifactId>transitive-dependency-artifactId</artifactId>
        <version>1</version>
        <distributionManagement>
          <relocation>
            <groupId>transitive-dependency-new-groupId</groupId>
          </relocation>
        </distributionManagement>
      </project>       
      
      <project>
        <modelVersion>4.0.0</modelVersion>
        <groupId>transitive-dependency-new-groupId</groupId>
        <artifactId>transitive-dependency-artifactId</artifactId>
        <version>1</version>
        <dependencies>
          <dependency>
            <groupId>other-groupId</groupId>
            <artifactId>other-artifactId-a</artifactId>
            <version>1</version>
          </dependency>
        </dependencies>
      </project>
      
      <project>
        <modelVersion>4.0.0</modelVersion>
        <groupId>transitive-dependency-new-groupId</groupId>
        <artifactId>transitive-dependency-artifactId</artifactId>
        <version>2</version>
        <dependencies>
          <dependency>
            <groupId>other-groupId</groupId>
            <artifactId>other-artifactId-a</artifactId>
            <version>1</version>
          </dependency>
          <dependency>
            <groupId>other-groupId</groupId>
            <artifactId>other-artifactId-b</artifactId>
            <version>1</version>
          </dependency>
        </dependencies>
      </project>
      
      --------------------------------------------------------------        
      actual dependency:tree 
          
       root-groupId:root-artifactId:jar:1
       \- direct-dependency-groupId:direct-dependency-artifactId:jar:1:compile
          \- transitive-dependency-new-groupId:transitive-dependency-artifactId:jar:2:compile (version managed from 1)
             \- other-groupId:other-artifactId-a:jar:1:compile           
      -------------------------------------------------------------- 
      expected dependency:tree 
          
       root-groupId:root-artifactId:jar:1
       \- direct-dependency-groupId:direct-dependency-artifactId:jar:1:compile
          \- transitive-dependency-new-groupId:transitive-dependency-artifactId:jar:2:compile (version managed from 1)
             \- other-groupId:other-artifactId-a:jar:1:compile    
             \- other-groupId:other-artifactId-b:jar:1:compile <-- missing from actual result    
      -------------------------------------------------------------- 
      

      As you can see from the listing above, other-groupId:other-artifactId-b:jar:1:compile is missing from the dependency list.

      I have attached the zipped repo which was used when generating the dependency:tree listings shown above. I also attached a crude temporary patch which my team is currently using to resolve this issue. After ignoring whitespace changes, it is about 10 lines different.

      Thanks,

      Luke

      1. MNG-3380-integration-test.zip
        22 kB
        luke w patterson
      2. MNG-3380-maven-artifact.patch
        11 kB
        luke w patterson
      3. patch.txt
        11 kB
        luke w patterson
      4. repo.zip
        13 kB
        luke w patterson

        Activity

        Hide
        Siveton Vincent added a comment -
        Show
        Siveton Vincent added a comment - Could you send us a patch according [1] . Thanks! [1] http://maven.apache.org/guides/development/guide-m2-development.html#Creating_and_submitting_a_patch
        Hide
        luke w patterson added a comment -

        Thanks for the info, Vincent. Please let me know if the new patch is better.

        Just keep in mind that the patch is not elegant at all. Basically, I check to see if ArtifactMetadataSource changes the artifact (due to relocation) when it retrieves ResolutionGroup. If it does change it, I repeat the portion of code that checks for managed versions. That was a quick hack because I couldn't find a place in the logic which was aware of all factors involved.

        Thanks,

        Luke

        Show
        luke w patterson added a comment - Thanks for the info, Vincent. Please let me know if the new patch is better. Just keep in mind that the patch is not elegant at all. Basically, I check to see if ArtifactMetadataSource changes the artifact (due to relocation) when it retrieves ResolutionGroup. If it does change it, I repeat the portion of code that checks for managed versions. That was a quick hack because I couldn't find a place in the logic which was aware of all factors involved. Thanks, Luke
        Hide
        Wojciech Ciesielski added a comment -

        If I understand this issue well then this is exactly the same problem we're having with xerces...
        groovy 1.0 (from repo1.maven.org) has dependency to xerces:xerces:jar:2.4.0 which has been relocated to xerces:xercesImpl:2.4.0. I do have xerces:xercesImpl:2.6.2 in dependencyManagement of root POM for our set of projects (modules) but when a module (web module) depending on both xerces:xercesImpl and groovy is built, then BOTH xerces libs are bundled: 2.4 (from relocation) and 2.6.2 (from dep. mgmnt.)...

        Show
        Wojciech Ciesielski added a comment - If I understand this issue well then this is exactly the same problem we're having with xerces... groovy 1.0 (from repo1.maven.org) has dependency to xerces:xerces:jar:2.4.0 which has been relocated to xerces:xercesImpl:2.4.0. I do have xerces:xercesImpl:2.6.2 in dependencyManagement of root POM for our set of projects (modules) but when a module (web module) depending on both xerces:xercesImpl and groovy is built, then BOTH xerces libs are bundled: 2.4 (from relocation) and 2.6.2 (from dep. mgmnt.)...
        Hide
        luke w patterson added a comment -

        Wojciech,

        Is this the scenario you are describing?

        <project>
        <modelVersion>4.0.0</modelVersion>
        <groupId>parent-groupId</groupId>
        <artifactId>parent-artifactId</artifactId>
        <version>1</version>
        <packaging>pom</packaging>
        <dependencyManagement>
        <dependencies>
        <dependency>
        <groupId>xerces</groupId>
        <artifactId>xercesImpl</artifactId>
        <version>2.6.2</version>
        </dependency>
        </dependencies>
        </dependencyManagement>
        </project>

        <project>
        <parent>
        <groupId>parent-groupId</groupId>
        <artifactId>parent-artifactId</artifactId>
        <version>1</version>
        </parent>
        <modelVersion>4.0.0</modelVersion>
        <artifactId>child-artifactId</artifactId>
        <dependencies>
        <dependency>
        <groupId>xerces</groupId>
        <artifactId>xercesImpl</artifactId>
        </dependency>
        <dependency>
        <groupId>groovy</groupId>
        <artifactId>groovy</artifactId>
        <version>1.0</version>
        </dependency>
        </dependencies>
        </project>

        If so, 2.0.8 seemed to handle it correctly:

        [dependency:tree]
        parent-groupId:child-artifactId:jar:1
        +- xerces:xercesImpl:jar:2.6.2:compile
        - groovy:groovy:jar:1.0:compile
        +- antlr:antlr:jar:2.7.5:compile
        +- asm:asm:jar:2.2:compile
        +- (xerces:xercesImpl:jar:2.6.2:compile - version managed from 2.4.0; omitted for duplicate)
        +- xml-apis:xml-apis:jar:1.0.b2:compile
        +- commons-cli:commons-cli:jar:1.0:compile

        +- (commons-logging:commons-logging:jar:1.0:compile - omitted for conflict with 1.0.4)
        - commons-lang:commons-lang:jar:1.0:compile
        - (junit:junit:jar:3.7:compile - omitted for conflict with 3.8.2)
        +- ant:ant:jar:1.6.5:compile
        +- ant:ant-junit:jar:1.6.5:compile
        +- ant:ant-launcher:jar:1.6.5:compile
        +- junit:junit:jar:3.8.2:compile
        +- jmock:jmock:jar:1.1.0:compile
        - (junit:junit:jar:3.8.1:compile - omitted for conflict with 3.8.2)
        +- jmock:jmock-cglib:jar:1.1.0:compile
        +- (jmock:jmock:jar:1.1.0:compile - omitted for duplicate)
        - cglib:cglib-full:jar:2.0:compile
        +- cglib:cglib-nodep:jar:2.1_3:compile
        +- asm:asm-util:jar:2.2:compile
        +- asm:asm-attrs:jar:2.2:compile
        +- asm:asm-analysis:jar:2.2:compile
        +- asm:asm-tree:jar:2.2:compile
        +- bsf:bsf:jar:2.4.0:compile
        - (commons-logging:commons-logging:jar:1.0.4:compile - omitted for conflict with 1.0)
        +- mx4j:mx4j:jar:3.0.1:compile
        +- mockobjects:mockobjects-core:jar:0.09:compile
        +- openejb:openejb-loader:jar:1.0:compile
        +- openejb:openejb-core:jar:1.0:compile
          +- (org.apache.geronimo.specs:geronimo-jta_1.0.1B_spec:jar:1.0:compile - omitted for duplicate)
          +- (org.apache.geronimo.specs:geronimo-ejb_2.1_spec:jar:1.0:compile - omitted for duplicate)
          +- (org.apache.geronimo.specs:geronimo-j2ee-connector_1.5_spec:jar:1.0:compile - omitted for duplicate)
          +- (org.apache.geronimo.specs:geronimo-servlet_2.4_spec:jar:1.0:compile - omitted for duplicate)
          +- (log4j:log4j:jar:1.2.8:compile - omitted for duplicate)
          +- backport-util-concurrent:backport-util-concurrent:jar:2.0_01_pd:compile
          +- (xerces:xercesImpl:jar:2.6.2:compile - version managed from 2.6.0; omitted for duplicate)
          +- (xml-apis:xml-apis:jar:1.0.b2:compile - omitted for duplicate)
          +- castor:castor:jar:0.9.9.0-pre:compile
          +- oro:oro:jar:2.0.8:compile
          +- (commons-logging:commons-logging:jar:1.0.3:compile - omitted for conflict with 1.0)
          - idb:idb:jar:3.26:compile
        +- org.apache.geronimo.specs:geronimo-jta_1.0.1B_spec:jar:1.0:compile
        +- org.apache.geronimo.specs:geronimo-ejb_2.1_spec:jar:1.0:compile
        +- org.apache.geronimo.specs:geronimo-j2ee-connector_1.5_spec:jar:1.0:compile
        +- org.apache.geronimo.specs:geronimo-servlet_2.4_spec:jar:1.0:compile
        - log4j:log4j:jar:1.2.8:compile
        +- axion:axion:jar:1.0-M3-dev:compile
        +- (commons-collections:commons-collections:jar:3.0:compile - omitted for conflict with 3.2)
        +- (commons-primitives:commons-primitives:jar:1.0:compile - omitted for duplicate)
        +- (commons-logging:commons-logging:jar:1.0:compile - omitted for duplicate)
        +- commons-codec:commons-codec:jar:1.2:compile
        +- (junit:junit:jar:3.8.1:compile - omitted for conflict with 3.8.2)
        - net.java.dev.javacc:javacc:jar:3.2:compile
        +- commons-logging:commons-logging:jar:1.0.4:compile
        +- commons-collections:commons-collections:jar:3.2:compile
        +- commons-primitives:commons-primitives:jar:1.0:compile
        +- regexp:regexp:jar:1.3:compile
        +- javax.servlet:servlet-api:jar:2.4:compile
        +- javax.servlet:jsp-api:jar:2.0:compile
        - (javax.servlet:servlet-api:jar:2.4:compile - omitted for duplicate)
        +- radeox:radeox:jar:0.9:compile
        +- radeox:radeox-oro:jar:0.9:compile
        +- nekohtml:nekohtml:jar:0.9.5:compile
        - (xerces:xercesImpl:jar:2.6.2:compile - version managed from 2.4.0; omitted for duplicate)
        +- qdox:qdox:jar:1.5:compile
        +- commons-httpclient:commons-httpclient:jar:3.0.1:compile
        +- (junit:junit:jar:3.8.1:compile - omitted for conflict with 3.8.2)
        +- (commons-logging:commons-logging:jar:1.0.3:compile - omitted for conflict with 1.0.4)
        - (commons-codec:commons-codec:jar:1.2:compile - omitted for duplicate)
        +- com.thoughtworks.xstream:xstream:jar:1.2:compile
        - xpp3:xpp3_min:jar:1.1.3.4.O:compile
        +- xpp3:xpp3:jar:1.1.3.4.O:compile
        - com.tonicsystems:jarjar:jar:0.6:compile

        Do you have a minimal example you can send me? Can it be demonstrated via dependency:tree listings?

        Show
        luke w patterson added a comment - Wojciech, Is this the scenario you are describing? <project> <modelVersion>4.0.0</modelVersion> <groupId>parent-groupId</groupId> <artifactId>parent-artifactId</artifactId> <version>1</version> <packaging>pom</packaging> <dependencyManagement> <dependencies> <dependency> <groupId>xerces</groupId> <artifactId>xercesImpl</artifactId> <version>2.6.2</version> </dependency> </dependencies> </dependencyManagement> </project> <project> <parent> <groupId>parent-groupId</groupId> <artifactId>parent-artifactId</artifactId> <version>1</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>child-artifactId</artifactId> <dependencies> <dependency> <groupId>xerces</groupId> <artifactId>xercesImpl</artifactId> </dependency> <dependency> <groupId>groovy</groupId> <artifactId>groovy</artifactId> <version>1.0</version> </dependency> </dependencies> </project> If so, 2.0.8 seemed to handle it correctly: [dependency:tree] parent-groupId:child-artifactId:jar:1 +- xerces:xercesImpl:jar:2.6.2:compile - groovy:groovy:jar:1.0:compile +- antlr:antlr:jar:2.7.5:compile +- asm:asm:jar:2.2:compile +- (xerces:xercesImpl:jar:2.6.2:compile - version managed from 2.4.0; omitted for duplicate) +- xml-apis:xml-apis:jar:1.0.b2:compile +- commons-cli:commons-cli:jar:1.0:compile +- (commons-logging:commons-logging:jar:1.0:compile - omitted for conflict with 1.0.4) - commons-lang:commons-lang:jar:1.0:compile - (junit:junit:jar:3.7:compile - omitted for conflict with 3.8.2) +- ant:ant:jar:1.6.5:compile +- ant:ant-junit:jar:1.6.5:compile +- ant:ant-launcher:jar:1.6.5:compile +- junit:junit:jar:3.8.2:compile +- jmock:jmock:jar:1.1.0:compile - (junit:junit:jar:3.8.1:compile - omitted for conflict with 3.8.2) +- jmock:jmock-cglib:jar:1.1.0:compile +- (jmock:jmock:jar:1.1.0:compile - omitted for duplicate) - cglib:cglib-full:jar:2.0:compile +- cglib:cglib-nodep:jar:2.1_3:compile +- asm:asm-util:jar:2.2:compile +- asm:asm-attrs:jar:2.2:compile +- asm:asm-analysis:jar:2.2:compile +- asm:asm-tree:jar:2.2:compile +- bsf:bsf:jar:2.4.0:compile - (commons-logging:commons-logging:jar:1.0.4:compile - omitted for conflict with 1.0) +- mx4j:mx4j:jar:3.0.1:compile +- mockobjects:mockobjects-core:jar:0.09:compile +- openejb:openejb-loader:jar:1.0:compile +- openejb:openejb-core:jar:1.0:compile   +- (org.apache.geronimo.specs:geronimo-jta_1.0.1B_spec:jar:1.0:compile - omitted for duplicate)   +- (org.apache.geronimo.specs:geronimo-ejb_2.1_spec:jar:1.0:compile - omitted for duplicate)   +- (org.apache.geronimo.specs:geronimo-j2ee-connector_1.5_spec:jar:1.0:compile - omitted for duplicate)   +- (org.apache.geronimo.specs:geronimo-servlet_2.4_spec:jar:1.0:compile - omitted for duplicate)   +- (log4j:log4j:jar:1.2.8:compile - omitted for duplicate)   +- backport-util-concurrent:backport-util-concurrent:jar:2.0_01_pd:compile   +- (xerces:xercesImpl:jar:2.6.2:compile - version managed from 2.6.0; omitted for duplicate)   +- (xml-apis:xml-apis:jar:1.0.b2:compile - omitted for duplicate)   +- castor:castor:jar:0.9.9.0-pre:compile   +- oro:oro:jar:2.0.8:compile   +- (commons-logging:commons-logging:jar:1.0.3:compile - omitted for conflict with 1.0)   - idb:idb:jar:3.26:compile +- org.apache.geronimo.specs:geronimo-jta_1.0.1B_spec:jar:1.0:compile +- org.apache.geronimo.specs:geronimo-ejb_2.1_spec:jar:1.0:compile +- org.apache.geronimo.specs:geronimo-j2ee-connector_1.5_spec:jar:1.0:compile +- org.apache.geronimo.specs:geronimo-servlet_2.4_spec:jar:1.0:compile - log4j:log4j:jar:1.2.8:compile +- axion:axion:jar:1.0-M3-dev:compile +- (commons-collections:commons-collections:jar:3.0:compile - omitted for conflict with 3.2) +- (commons-primitives:commons-primitives:jar:1.0:compile - omitted for duplicate) +- (commons-logging:commons-logging:jar:1.0:compile - omitted for duplicate) +- commons-codec:commons-codec:jar:1.2:compile +- (junit:junit:jar:3.8.1:compile - omitted for conflict with 3.8.2) - net.java.dev.javacc:javacc:jar:3.2:compile +- commons-logging:commons-logging:jar:1.0.4:compile +- commons-collections:commons-collections:jar:3.2:compile +- commons-primitives:commons-primitives:jar:1.0:compile +- regexp:regexp:jar:1.3:compile +- javax.servlet:servlet-api:jar:2.4:compile +- javax.servlet:jsp-api:jar:2.0:compile - (javax.servlet:servlet-api:jar:2.4:compile - omitted for duplicate) +- radeox:radeox:jar:0.9:compile +- radeox:radeox-oro:jar:0.9:compile +- nekohtml:nekohtml:jar:0.9.5:compile - (xerces:xercesImpl:jar:2.6.2:compile - version managed from 2.4.0; omitted for duplicate) +- qdox:qdox:jar:1.5:compile +- commons-httpclient:commons-httpclient:jar:3.0.1:compile +- (junit:junit:jar:3.8.1:compile - omitted for conflict with 3.8.2) +- (commons-logging:commons-logging:jar:1.0.3:compile - omitted for conflict with 1.0.4) - (commons-codec:commons-codec:jar:1.2:compile - omitted for duplicate) +- com.thoughtworks.xstream:xstream:jar:1.2:compile - xpp3:xpp3_min:jar:1.1.3.4.O:compile +- xpp3:xpp3:jar:1.1.3.4.O:compile - com.tonicsystems:jarjar:jar:0.6:compile Do you have a minimal example you can send me? Can it be demonstrated via dependency:tree listings?
        Hide
        luke w patterson added a comment -

        The problem still exists with 2.0.9.

        Until the bug is fixed, the assembly plugin I'm using won't receive accurate information.

        Relocated transitive dependencies can be either missing or wrong during tree resolution.

        Show
        luke w patterson added a comment - The problem still exists with 2.0.9. Until the bug is fixed, the assembly plugin I'm using won't receive accurate information. Relocated transitive dependencies can be either missing or wrong during tree resolution.
        Hide
        luke w patterson added a comment -

        new integration test

        Show
        luke w patterson added a comment - new integration test
        Hide
        luke w patterson added a comment -

        I attached a new integration test for this condition. (MNG-3380-integration-test.zip)

        The test fails in all of these:

        2.0.7
        2.0.8
        2.0.9
        2.1-SNAPSHOT (rev 649863 of trunk)

        Without a fix, plugins cannot rely on org.apache.maven.project.MavenProject#getArtifacts(). Results could be inaccurate if you use dependencyManagement and have relocated transitive dependencies.

        Summary of integration test:
        ---------------------------------------------------------------
        project.getArtifacts()

        direct-dependency-groupId:direct-dependency-artifactId:jar:1:compile
        transitive-dependency-new-groupId:transitive-dependency-artifactId:jar:2:compile
        other-groupId:other-artifactId-a:jar:1:compile
        other-groupId:other-artifactId-b:jar:1:compile <-- should be here, but isn't
        other-groupId:other-artifactId-c:jar:1:compile <-- is here, but shouldn't be
        ---------------------------------------------------------------

        Show
        luke w patterson added a comment - I attached a new integration test for this condition. ( MNG-3380 -integration-test.zip) The test fails in all of these: 2.0.7 2.0.8 2.0.9 2.1-SNAPSHOT (rev 649863 of trunk) Without a fix, plugins cannot rely on org.apache.maven.project.MavenProject#getArtifacts(). Results could be inaccurate if you use dependencyManagement and have relocated transitive dependencies. Summary of integration test: --------------------------------------------------------------- project.getArtifacts() direct-dependency-groupId:direct-dependency-artifactId:jar:1:compile transitive-dependency-new-groupId:transitive-dependency-artifactId:jar:2:compile other-groupId:other-artifactId-a:jar:1:compile other-groupId:other-artifactId-b:jar:1:compile <-- should be here, but isn't other-groupId:other-artifactId-c:jar:1:compile <-- is here, but shouldn't be ---------------------------------------------------------------
        Hide
        John Casey added a comment -

        This is fixed on the 2.0.x branch, and I've incorporated an integration test based on the MNG-3380-integration-test.zip (I changed it to fail compilation and unit testing, rather than requiring a separate plugin to verify things).

        The only thing that I need to finish up is the fix for trunk (2.1) before I close this issue.

        Show
        John Casey added a comment - This is fixed on the 2.0.x branch, and I've incorporated an integration test based on the MNG-3380 -integration-test.zip (I changed it to fail compilation and unit testing, rather than requiring a separate plugin to verify things). The only thing that I need to finish up is the fix for trunk (2.1) before I close this issue.
        Hide
        John Casey added a comment -

        I modified the artifact collector (and artifact metadata source) to allow the resolution of all project relocations before attempting to resolve the child nodes.

        Show
        John Casey added a comment - I modified the artifact collector (and artifact metadata source) to allow the resolution of all project relocations before attempting to resolve the child nodes.
        Hide
        luke w patterson added a comment -

        I tested with 2.0.10-RC2 [1] the production scenario that originally highlighted this issue. Issue Resolved.

        Thanks for your dedicated effort in moving 2.0.10 along.

        [1] - http://people.apache.org/~jdcasey/stage/apache-maven/2.0.10-RC2

        Show
        luke w patterson added a comment - I tested with 2.0.10-RC2 [1] the production scenario that originally highlighted this issue. Issue Resolved. Thanks for your dedicated effort in moving 2.0.10 along. [1] - http://people.apache.org/~jdcasey/stage/apache-maven/2.0.10-RC2
        Hide
        John Casey added a comment -

        Adding fix-for for both 2.0.10 and 2.1.0-M1, since 2.1.0-M1 will actually be released first and may not incorporate all of the eventual issue fixes released in 2.0.10.

        Show
        John Casey added a comment - Adding fix-for for both 2.0.10 and 2.1.0-M1, since 2.1.0-M1 will actually be released first and may not incorporate all of the eventual issue fixes released in 2.0.10.

          People

          • Assignee:
            John Casey
            Reporter:
            luke w patterson
          • Votes:
            7 Vote for this issue
            Watchers:
            4 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development