Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 2.0
    • Fix Version/s: 2.0.9
    • Component/s: Dependencies
    • Labels:
      None

      Description

      The .classpath file entries should be ordered by nearest transitiveness (if that's a word).

      For example, I have project A that depends on B that depends on C. The classpath for A is generated in the order C, B. Ideally the classpath should be in order of how near they are to the project, i.e. B, C.

      1. MNG-1412-maven-2.0.x-r507746.patch
        18 kB
      2. MNG-1412_dependency_sorting.tgz
        1 kB
        Hervé Boutemy
      3. artifact-order_maven-project.txt
        10 kB
        Martin Zeltner
      4. artifact-order_maven-artifact-manager.txt
        7 kB
        Martin Zeltner
      5. artifact-order_maven-artifact.txt
        9 kB
        Martin Zeltner

        Issue Links

          Activity

          Hide
          fabrizio giustina added a comment -

          Is there a reason for this order or it's only a "cosmetic" reason? AFAIK unless you have the same classes in multiple dependencies the order has no effect.

          Show
          fabrizio giustina added a comment - Is there a reason for this order or it's only a "cosmetic" reason? AFAIK unless you have the same classes in multiple dependencies the order has no effect.
          Hide
          fabrizio giustina added a comment -

          Please reopen the issue if you can find a valid reason why this kind of order is needed; in the meanwhile I'm closing the issue since the order actually used for the eclipse classpath is the same order used by maven during compilation and IMHO this is definitively the correct behaviour.

          Show
          fabrizio giustina added a comment - Please reopen the issue if you can find a valid reason why this kind of order is needed; in the meanwhile I'm closing the issue since the order actually used for the eclipse classpath is the same order used by maven during compilation and IMHO this is definitively the correct behaviour.
          Hide
          Mark Hobson added a comment -

          This is mainly required when dealing with resources within dependencies. An example would be that projects B and C both contain a log4j.properties file and you want to always pick up the nearest one. At the moment C's log4j.properties file would be used in preference to B's, which seems a bit unintuitive. Eclipse does allow you to manually reorder the classpath but this is tedious and error prone.

          Show
          Mark Hobson added a comment - This is mainly required when dealing with resources within dependencies. An example would be that projects B and C both contain a log4j.properties file and you want to always pick up the nearest one. At the moment C's log4j.properties file would be used in preference to B's, which seems a bit unintuitive. Eclipse does allow you to manually reorder the classpath but this is tedious and error prone.
          Hide
          fabrizio giustina added a comment -

          Checking the classpath used by maven when running tests and the .classpath file generated by the eclipse plugin it seems that the order is preserved. Since the purpose of the plugin is to make the eclipse environment match as close as possible the maven one, this should not be changed (do you get different result with your log4.properties case when running maven directly?).

          If dependencies should be sorted in a different order, this should be done in the maven core: I am moving this issue from the eclipse component to core (leaving component as unknown, since there is no more "core" or "dependency resolution" component)

          Show
          fabrizio giustina added a comment - Checking the classpath used by maven when running tests and the .classpath file generated by the eclipse plugin it seems that the order is preserved. Since the purpose of the plugin is to make the eclipse environment match as close as possible the maven one, this should not be changed (do you get different result with your log4.properties case when running maven directly?). If dependencies should be sorted in a different order, this should be done in the maven core: I am moving this issue from the eclipse component to core (leaving component as unknown, since there is no more "core" or "dependency resolution" component)
          Hide
          Mark Hobson added a comment -

          Yes, sorry, the ordering is the same as in maven itself - I didn't mean to imply otherwise. Moving to maven core gets my vote, thanks.

          Show
          Mark Hobson added a comment - Yes, sorry, the ordering is the same as in maven itself - I didn't mean to imply otherwise. Moving to maven core gets my vote, thanks.
          Hide
          Martin Zeltner added a comment -

          I've patched Maven so you get the same order of artifacts how they are defined in poms. I've just replaced "java.util.HashMap" with "java.util.LinkedHashMap" and "java.util.HashSet" with "java.util.LinkedHashSet" in following modules of project "components":
          maven-artifact, maven-artifact-manager and maven-project. I don't know if there are other modules where this replacement should be made, for example the execution order of mojos in the same phase.

          Appended you can find the patch files for the revision of yesterday.

          Cheers,
          Martin

          Show
          Martin Zeltner added a comment - I've patched Maven so you get the same order of artifacts how they are defined in poms. I've just replaced "java.util.HashMap" with "java.util.LinkedHashMap" and "java.util.HashSet" with "java.util.LinkedHashSet" in following modules of project "components": maven-artifact, maven-artifact-manager and maven-project. I don't know if there are other modules where this replacement should be made, for example the execution order of mojos in the same phase. Appended you can find the patch files for the revision of yesterday. Cheers, Martin
          Hide
          Holger Hoffstätte added a comment -

          I want to add another point of view and request ordering of exported jars by name, at least as option. While I can understand Mark's use case for controlling export ordering (POM order is a good step forward from the current way), I like to think of the need for a properly ordered classpath as a build management bug in the first place. This should just not be an issue for IDE development; I'd venture the guess that quickly finding classes in a list of jars is the much more common case. 99% of the time I am simply not interested in detailed dependency trees, and for launching I can still rearrange in the launch config.
          Looking at the patches it seems to me that an optional name ordering should not be much more complicated, e.g. by throwing everything into a TreeMap before output.

          Show
          Holger Hoffstätte added a comment - I want to add another point of view and request ordering of exported jars by name , at least as option. While I can understand Mark's use case for controlling export ordering (POM order is a good step forward from the current way), I like to think of the need for a properly ordered classpath as a build management bug in the first place. This should just not be an issue for IDE development; I'd venture the guess that quickly finding classes in a list of jars is the much more common case. 99% of the time I am simply not interested in detailed dependency trees, and for launching I can still rearrange in the launch config. Looking at the patches it seems to me that an optional name ordering should not be much more complicated, e.g. by throwing everything into a TreeMap before output.
          Hide
          Pablo Gutierrez added a comment -

          Sometimes there is a need to specify the order of the dependencies.
          Rigth now I'm in a situation where one jar overwrites some classes (not all)
          of some purchased library as didn't perform what we wanted.
          So in our jnlp's and scripts for launching our applications we have to specify one strict classpath order
          on jars. We are moving to Maven 2 but ran into this problem.

          Where can I download this fix? I need to use svn and build maven?

          Thanks

          Show
          Pablo Gutierrez added a comment - Sometimes there is a need to specify the order of the dependencies. Rigth now I'm in a situation where one jar overwrites some classes (not all) of some purchased library as didn't perform what we wanted. So in our jnlp's and scripts for launching our applications we have to specify one strict classpath order on jars. We are moving to Maven 2 but ran into this problem. Where can I download this fix? I need to use svn and build maven? Thanks
          Hide
          Holger Hoffstätte added a comment -

          Following up on my own comment about ordering for eclipse .classpath files: MECLIPSE-152

          Show
          Holger Hoffstätte added a comment - Following up on my own comment about ordering for eclipse .classpath files: MECLIPSE-152
          Hide
          Justin Edelson added a comment -

          Is this fix going to be in 2.1? I'm using a patched version of 2.0.4 as a result of it and have to distribute the three patched jars to all of our developers.

          Show
          Justin Edelson added a comment - Is this fix going to be in 2.1? I'm using a patched version of 2.0.4 as a result of it and have to distribute the three patched jars to all of our developers.
          Hide
          yogieric added a comment -

          Note that r430569 (committed into 2.0.5) does fix some of the related issues here.

          In fact, I'm not even completely clear on all the changes proposed in Marten's patches other than that they can't break things (just using Linked versions of HashMap and HashSet) and common-sense dictates they make sense in several places. My strong vote would be to commit this patch as I don't see anyway it could break anything. Tests would be nice, but given the random nature of items returned from non-Linked HashSet and HashMap collections, it is hard to validate that the tests would fail without these changes. Tests would be nice in the future to ensure things don't break again.

          This is an update of the patches Marten submitted against the maven-2.0.x post 2.0.5. I've removed a few changes where maps and sets were never converted collections or passed outside their local scope. Plus r430569 shrinks it a bit too. Hopefully that makes it smaller and easier to code review.

          Thanks to Marten for the initial work on these patches.

          Show
          yogieric added a comment - Note that r430569 (committed into 2.0.5) does fix some of the related issues here. In fact, I'm not even completely clear on all the changes proposed in Marten's patches other than that they can't break things (just using Linked versions of HashMap and HashSet) and common-sense dictates they make sense in several places. My strong vote would be to commit this patch as I don't see anyway it could break anything. Tests would be nice, but given the random nature of items returned from non-Linked HashSet and HashMap collections, it is hard to validate that the tests would fail without these changes. Tests would be nice in the future to ensure things don't break again. This is an update of the patches Marten submitted against the maven-2.0.x post 2.0.5. I've removed a few changes where maps and sets were never converted collections or passed outside their local scope. Plus r430569 shrinks it a bit too. Hopefully that makes it smaller and easier to code review. Thanks to Marten for the initial work on these patches.
          Hide
          Sebastien Brunot added a comment -

          I've tried the new 2.0.5 version and the problem is still present in my case.

          For some reasons (that i cannot change), i'm using a library library-patch.jar that redefines a class of library.jar adding some extra methods to it.

          Whatever the order in which i declare the library-patch.jar and library.jar dependencies of my project, library.jar is always the first one in the classpath. So my project, which expect the patch class from library-patch.jar is not compiling.

          Show
          Sebastien Brunot added a comment - I've tried the new 2.0.5 version and the problem is still present in my case. For some reasons (that i cannot change), i'm using a library library-patch.jar that redefines a class of library.jar adding some extra methods to it. Whatever the order in which i declare the library-patch.jar and library.jar dependencies of my project, library.jar is always the first one in the classpath. So my project, which expect the patch class from library-patch.jar is not compiling.
          Hide
          Carlos Sanchez added a comment -

          if this is going to be implemented then a method that return something like a ListOrderedSet must be added. If you return an ordered Set it will be confusing.
          http://jakarta.apache.org/commons/collections/apidocs-COLLECTIONS_3_0/org/apache/commons/collections/set/ListOrderedSet.html

          Show
          Carlos Sanchez added a comment - if this is going to be implemented then a method that return something like a ListOrderedSet must be added. If you return an ordered Set it will be confusing. http://jakarta.apache.org/commons/collections/apidocs-COLLECTIONS_3_0/org/apache/commons/collections/set/ListOrderedSet.html
          Hide
          Ravi Luthra added a comment -

          Hi,

          The order of dependencies in the classPathElement does not follow the order as in pom.xml. It is never the same, I ran it on LINUX/Windows.. used the latest of Maven 2.04/2.0.5/2.0.6 .. with the latest JDK's.. but nothing helps. There is one behaviour I have noticed that when if the dependency you are trying to order is in the build path then only the order is not correct...

          Please help

          Show
          Ravi Luthra added a comment - Hi, The order of dependencies in the classPathElement does not follow the order as in pom.xml. It is never the same, I ran it on LINUX/Windows.. used the latest of Maven 2.04/2.0.5/2.0.6 .. with the latest JDK's.. but nothing helps. There is one behaviour I have noticed that when if the dependency you are trying to order is in the build path then only the order is not correct... Please help
          Hide
          Bryan Cooper added a comment -

          Perhaps an ordering attribute on the dependency itself would help in ordering. By default, the attribute doesn't need to be specified in the pom, but, be used by the module responsible for ordering the dependencies to store the default pom order of dependencies. This would also enable a simple sort via the Collections.sort utility.

          <dependency>
          <groupId>junit</groupId>
          <artifactId>junit</artifactId>
          <version>3.8.1</version>
          <scope>test</scope>
          <classpathOrder>1</classpathOrder> <-- New attribute
          </dependency>

          The attribute should be respected for building classpaths and even for adding a classpath to a manifest file.
          Also, transitive dependencies shoud be included directly prior to their first occurrance, but, not before.
          Hope to see some news on this issue soon.

          Show
          Bryan Cooper added a comment - Perhaps an ordering attribute on the dependency itself would help in ordering. By default, the attribute doesn't need to be specified in the pom, but, be used by the module responsible for ordering the dependencies to store the default pom order of dependencies. This would also enable a simple sort via the Collections.sort utility. <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.1</version> <scope>test</scope> <classpathOrder>1</classpathOrder> <-- New attribute </dependency> The attribute should be respected for building classpaths and even for adding a classpath to a manifest file. Also, transitive dependencies shoud be included directly prior to their first occurrance, but, not before. Hope to see some news on this issue soon.
          Hide
          Knut Forkalsrud added a comment -

          I would think the most common example for this would be log4j static initialization

          We don't want to configure logging explicitly in unit tests, so we rely on log4j's
          builtin lookup of "log4j.properties". Unfortunately way too many third party
          jars contain one of these so we need the directory target/test-classes to be
          first on the classpath. One can argue that log4j's approach isn't the best, but it
          is the standard for practical purposes.

          Show
          Knut Forkalsrud added a comment - I would think the most common example for this would be log4j static initialization We don't want to configure logging explicitly in unit tests, so we rely on log4j's builtin lookup of "log4j.properties". Unfortunately way too many third party jars contain one of these so we need the directory target/test-classes to be first on the classpath. One can argue that log4j's approach isn't the best, but it is the standard for practical purposes.
          Hide
          Michael Buckley added a comment -

          I vote for a stable order in the .classpath file. We commit these to SVN to simplify eclipse usage, and rebuilding them on different machines generates spurious diffs. If fact, just adding -DdownloadSources=true generates different orders.

          Show
          Michael Buckley added a comment - I vote for a stable order in the .classpath file. We commit these to SVN to simplify eclipse usage, and rebuilding them on different machines generates spurious diffs. If fact, just adding -DdownloadSources=true generates different orders.
          Hide
          nicolas de loof added a comment -

          I can understand this classpath ordering requirement for a command line application point of view, where the classpath variable is under control, but what in a JEE context where all jars are put in WEB-INF/lib and not ordering can be specified ?

          Having a project to depend on classpath ordering is simply a nonsense for me. This sounds like a hack to bypass some architecture issues.

          You have multiple log4j.properties in classpath ? Having multiple result for a resource lookup is a valid Java case (@see Classloader.getResources()) but IS NOT supported by log4j !

          • Why do those jars have a log4j.properties if they are not runnable artifacts ?
          • Why not setup log4j programmatically or using -Dlog4j.configuration ?

          for testing purpose, the taget/classes and taget/test-classes are set prior to dependencies in classpath, like the WEB-INF/classes is on a JEE webapp.

          You need to patch some 3d party jar ? Create a new project, use the dependency plugin to unpack it, add your custom patched classes and package your own modified artifact !

          Show
          nicolas de loof added a comment - I can understand this classpath ordering requirement for a command line application point of view, where the classpath variable is under control, but what in a JEE context where all jars are put in WEB-INF/lib and not ordering can be specified ? Having a project to depend on classpath ordering is simply a nonsense for me. This sounds like a hack to bypass some architecture issues. You have multiple log4j.properties in classpath ? Having multiple result for a resource lookup is a valid Java case (@see Classloader.getResources()) but IS NOT supported by log4j ! Why do those jars have a log4j.properties if they are not runnable artifacts ? Why not setup log4j programmatically or using -Dlog4j.configuration ? for testing purpose, the taget/classes and taget/test-classes are set prior to dependencies in classpath, like the WEB-INF/classes is on a JEE webapp. You need to patch some 3d party jar ? Create a new project, use the dependency plugin to unpack it, add your custom patched classes and package your own modified artifact !
          Hide
          Yuri Schimke added a comment -

          Yes you are probably right, its mainly architectural issues i.e. patch jars. But fixing it would save so much trouble for so many people. So why argue so passionately about not fixing it, when its a simple fix.

          If you need a "good" reason to fix it, then It is bizarre that there is no predictable order for the classpath, even alphabetical would be better than quasi-random.

          Show
          Yuri Schimke added a comment - Yes you are probably right, its mainly architectural issues i.e. patch jars. But fixing it would save so much trouble for so many people. So why argue so passionately about not fixing it, when its a simple fix. If you need a "good" reason to fix it, then It is bizarre that there is no predictable order for the classpath, even alphabetical would be better than quasi-random.
          Hide
          Robert Weissmann added a comment -

          I totally agree with Yuri and Bryan,

          there should be a simple algorithm delivering ALWAYS the same classpath order based on the dependency or some parameter, so I can influence it. This should not be soooo difficult, but would be very helpfull, expecially during migration phases, version changes and testings.

          In a production release Nicolas you are absolutely right, there should be no such dependency on the classpath order. But in all other cases it is extremly helpfull.

          I hope this will be fixed soon (I conciously say "fixed", because for me this is definitely a bug - I was supprised that there is no parameter to set the order).

          Thanks to all the guys working hard on this project. Happy new year for 2008 .

          Show
          Robert Weissmann added a comment - I totally agree with Yuri and Bryan, there should be a simple algorithm delivering ALWAYS the same classpath order based on the dependency or some parameter, so I can influence it. This should not be soooo difficult, but would be very helpfull, expecially during migration phases, version changes and testings. In a production release Nicolas you are absolutely right, there should be no such dependency on the classpath order. But in all other cases it is extremly helpfull. I hope this will be fixed soon (I conciously say "fixed", because for me this is definitely a bug - I was supprised that there is no parameter to set the order). Thanks to all the guys working hard on this project. Happy new year for 2008 .
          Hide
          richard rattigan added a comment -

          This should definitely be fixed.

          I would suggest depth-first traversal, in the order specified in the pom would work best. The first occurrence of a dependency visited in this order should determine it's position in the classpath.

          This should be very easy to implement, and it would allow full control over classpath ordering by the normal mechanisms of adding dependencies and excluding transitive dependencies. In addition, the relationship between the poms and the classpath would be very natural and intuitive.

          Patching jars should be a last resort - unless you're a proponent of fragile development methodologies...

          Show
          richard rattigan added a comment - This should definitely be fixed. I would suggest depth-first traversal, in the order specified in the pom would work best. The first occurrence of a dependency visited in this order should determine it's position in the classpath. This should be very easy to implement, and it would allow full control over classpath ordering by the normal mechanisms of adding dependencies and excluding transitive dependencies. In addition, the relationship between the poms and the classpath would be very natural and intuitive. Patching jars should be a last resort - unless you're a proponent of fragile development methodologies...
          Hide
          Robert Weissmann added a comment -

          Hi,

          many votes on changes on this one, but sine 2005 there is no response from the Asignee "fabrizio giustina". Is he still around ? And if not, how does this work that someone else takes over in case he left ?

          Maybe this is a dead thread.

          Anyone knows how this works ?

          Cheers, Robert.

          Show
          Robert Weissmann added a comment - Hi, many votes on changes on this one, but sine 2005 there is no response from the Asignee "fabrizio giustina". Is he still around ? And if not, how does this work that someone else takes over in case he left ? Maybe this is a dead thread. Anyone knows how this works ? Cheers, Robert.
          Hide
          Hervé Boutemy added a comment -

          I just wrote a JUnit test that proves the defect.

          And it shows that the sorting problem was still here in 2.0.8, but it is not here any more in 2.0.9-SNAPSHOT (I didn't check 2.1-SNAPSHOT).
          I fixed it on 2007/12/07 in r601095 (r601096 in trunk) while working on such a dependencies sorting issue in MANTTASKS-91: one HashSet to LinkedHashSet transformation had been forgotten...

          Now I need to transform this JUnit test in an integration test to ensure that no regression will happen in the future.

          Can somebody check that it is ok for him with 2.0.9-SNAPSHOT? I'm pretty sure it is ok given my JUnit test, but having someone confirm this would be even better.

          Show
          Hervé Boutemy added a comment - I just wrote a JUnit test that proves the defect. And it shows that the sorting problem was still here in 2.0.8, but it is not here any more in 2.0.9-SNAPSHOT (I didn't check 2.1-SNAPSHOT). I fixed it on 2007/12/07 in r601095 (r601096 in trunk) while working on such a dependencies sorting issue in MANTTASKS-91 : one HashSet to LinkedHashSet transformation had been forgotten... Now I need to transform this JUnit test in an integration test to ensure that no regression will happen in the future. Can somebody check that it is ok for him with 2.0.9-SNAPSHOT? I'm pretty sure it is ok given my JUnit test, but having someone confirm this would be even better.
          Hide
          Hervé Boutemy added a comment -

          fixed on 2007/12/07 in r601095 (r601096 in trunk)
          Integration test just added in r617974

          Show
          Hervé Boutemy added a comment - fixed on 2007/12/07 in r601095 (r601096 in trunk) Integration test just added in r617974
          Hide
          Martin Zeltner added a comment -

          Hurray!
          Have a nice day!
          Martin

          Show
          Martin Zeltner added a comment - Hurray! Have a nice day! Martin
          Hide
          John Casey added a comment -

          this would have an effect on the ordering of dependencies from a plugin's POM that are used in the plugin's classpath...not sure whether it would affect transitive-dependency selection when two deps are at the same level in the transitive hierarchy, but it seems plausible.

          I need to examine the commits related to this fix to see.

          Show
          John Casey added a comment - this would have an effect on the ordering of dependencies from a plugin's POM that are used in the plugin's classpath...not sure whether it would affect transitive-dependency selection when two deps are at the same level in the transitive hierarchy, but it seems plausible. I need to examine the commits related to this fix to see.

            People

            • Assignee:
              Hervé Boutemy
              Reporter:
              Mark Hobson
            • Votes:
              44 Vote for this issue
              Watchers:
              35 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:

                Development