On 26 Apr 07, at 8:20 AM 26 Apr 07, Jörg Schaible wrote:

Hi Jason,

Jason van Zyl wrote on Thursday, April 26, 2007 1:52 PM:

On 26 Apr 07, at 6:05 AM 26 Apr 07, Arik Kfir wrote:

IMO, if the project claims to be backwards-compatible, then it should
include the older classes. If they can exist side-by-side, there
should be no issue.


I don't think you can force every project to do this, and I think
that users would intuitively users expect that two versions of, say,
junit that are declared should show up. So what Jorg is
asking for is
not unreasonable and I'm really just trying to think of the
repercussions of allowing multiple versions i.e. do we have any
plugins keying off special versions of classes: the surefire plugin
for example. I think the JMock example is perfectly valid and is
something that could be addressed in 2.1 but here is my concern and
generally why we took the strategy of not allowing this to begin with:

The classpath order is now derived from the order of the listing of
the dependencies. So in a particular project what if one case
requires class C1 from version 1.0 of JMock, and another case that
requires class C1 from version 2.0 of JMock? How are you going to
satisfy those two conditions and in general how are you going to
protect against classes that have the same name in different
versions
of the JAR where both are needed?. When this case arises you are
going to need a form of paritioning, yes?

Well, Nat *is* a bright guy :) Although both versions share the same root package, they have no overlap in claases itself. It is the perfect case for a "slotted" artifact - both development branches can be used at same time. And they continue development in both.


They don't have to be slotted. Maven does not prevent you from using multiple versions on a system, which is what the slotting approach is for. It's only for a project, and it's technically not hard to admit multiple versions into the processing. This is not a technical problem.

Because you're
going to end
up requiring features from the new version which means using the
newer classes. If you are going to need some way to say "for this
group of tests use this version of JMock" and "for this other set of
tests use that version of JMock" then you've gotten yourself into a
case that cannot be satisfied easy.

If projects could guaranteed that version N and the next major
upgrade guaranteed compatibility of the intersection of classes in
the different versions and additions were a superset of that then
adding both versions would be fine. But this is often not the case
and you get into real problems because the general rule for major
version number changes is that the API can break which means that a
class in 2.0 could be significantly different in API and structure
then its equivalent in 1.0.

If the project does not play nice, Maven cannot help you. Look at the ASM nightmare. Plain CGLIB 2.x depends on ASM 1.x while popular packages like Hibernate-3 or Groovy use ASM 2.x. Unfortunately both ASM versions are not compatible and either you break the artifacts depending on CGLIB or the other ones. CGLIB solved this by the - nodep artifact that contains the necessary ASM 1.x classes with a different package name, but, alas, this is also quite a hack. However, this mess was caused by the ASM project team itself.

I don't think the uber JAR approach works as well as child first loading classloaders so that you can use multiple versions of a library. Much like a webapp where two webapps could easily use different versions of CGLIB. But I think the uber JAR approach where a transitive hull is used to reduce the payload and then mange non- public interfaces is a fine approach.


In Ant you might create a separate classpath with different JARs and
apply that to a different set of classes. We avoid this by simply
saying, this is just too complicated and take your tests, create
another module that uses the new version of JMock and be done with it.

What is easier: creating a separate module which has this
simple rule
of allowing only one version of a dependency and using all the same
patterns of every other type of Maven module. Or allow multiple
versions and then start trying to rig up ways to defend against
incompatibilities and partitioning sets of classes for use with a
particular dependency? I think just making another module is easier.

Therefore the slots. The project itself can introduce them, if two major versions can be used at same time. Think about a hypothetical commons-logging 2.0 (it is discussed) that might have a different API. I am quite sure Jakarta folks will ensure that 2.x and 1.x series can be used at the same time - simply because even in the Maven repo itself ~ 2000 artifacts depend on it. Without something like the slots, you will never be able to create a new Maven-based project using JCL 2.x ...

I don't think we need to introduce the idea of slots. Allowing multiple versions would suffice. I don't see what the slot concept buys anyone except another term to be familiar with.


Are you sure you can defend against and cope with the two
versions of
JMock without any problem? Nat is a bright guy, and is probably very
careful about changes between versions but lots of project are not
and we decided not to allow multiple versions to protect people from
less then stringent practices that generally happen in real life.

Yep.

We tried to make the rules for a single module simple, and make it
simple to create new one. It's just so much easier for the rest of
the tool chain to understand then trying to deal with the
innumerable
variations that occurs when multiple anything is allowed: multiple
versions, multiple source trees, and multiple artifacts per unit of
work which is a POM/module in Maven.

That's the not so short answer, but the reason why we do what we do.
I know what users expect to happen, but try to think of the counter
examples where things might go wrong by using multiple versions in
the same module.

If your project cannot define the deps directly, the module approach does not work. See the JCL example.

Yes, it works if they are separate modules. But as I said above it is not a technical problem to allow multiple versions of JMock for example. At first blush I just see this causing more problems then viable solutions.

Jason.


- Jörg

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]




---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to