I like to consider a G:A as being substitutable along the V access... if you change the artifact so that it is not substitutable, then you really need to change the G:A part.
Now substitutable does not mean no breaking API changes... it does mean that the package name and at least some of the class names are the same. So a good case in point here is Jackson the JSON serialization library... There are many versions of Jackson, but when a major breaking change to the API was required Tatu changed from org.codehaus.jackson:jackson-core-asl to com.fasterxml.jackson.core:jackson-core and also changed the package name of the classes. This was the correct thing to do, IMHO. They maintained 82 releases of the API without having to refactor in a breaking way. The changes that they needed would break the API, leaving no way for existing code to inter-op As a result, by changing package name and G:A the two versions can co-exist... Now let us consider some other ways that Tatu & Co could have handled this: * They could have kept the package name the same and changed the G:A. That would mean that classes in the package name would not be coming from the same jar file, and so with a security manager enabled the "same jar origin policy" would mean that at run time you end up getting class conflicts all over the place as different classloaders resolve the package name from different jar files depending on which class they reference first and the order of the jars in the classpath... sounds a lot like hell... let's scrap that plan * They could have changed the package name and kept the G:A. That would mean that any fool* using version ranges could now find that their code fails to compile. (*only a fool uses version ranges)... that is self inflicted hell... also dependencyManagement will overrule versions so if somebody uses a dependencyManagement to force a version that will force a single version even though the classpath *should* have two versions... plus how Maven resolves the dependency tree means that it assumes that for any G:A varying the V gives you substitutable artifacts (and if they don't work then either `compile` or `test/verify` will fail the build so that's ok) So the rule of thumb I use is: * every time you change the package name, change the G:A * if you are making breaking API changes that are not substitutable, change the package name # aside Is there a use case for dependencies of the same GA but different V? I think there may be, at least when dealing with non-java resources... and Java 9 / OSGi provides a use case also. For example, you may have a legitimate (if crappy) reason to include two versions of jQuery in your web application... one set of pages may use the older one during a transition for example. So in modelVersion 5.0.0, I do think that we should investigate a means of flagging that certain types of dependency collection require a single unique version resolved for each GA dependency, while other types of dependency collection require the set of versions for each GA dependency On 14 January 2014 00:24, KARR, DAVID <[email protected]> wrote: > I have a situation where it would be convenient for my pom to have two > dependencies that are almost identical, only being different by the > version. The makeup of the artifact is such that it would be safe (and > intended) to use both of them. The Java package used in each is similar, > but different. The package will vary along with the version number. > > Will dependency resolution and the EAR plugin (and any other mechanism > that lists dependencies) have any trouble with this? > > --------------------------------------------------------------------- > To unsubscribe, e-mail: [email protected] > For additional commands, e-mail: [email protected] > >
