On 10/29/06, Stephen Colebourne <[EMAIL PROTECTED]> wrote:
PROPOSAL:
The major version number of a component, where it is greater than 1,
shall be included in the package name.

EXAMPLE:
org.apache.commons.pool - version 1.x line
org.apache.commons.pool2 - version 2.x line

RATIONALE:
Java has no mechanism for handling different versions of the same
library where those versions clash. This leads to a situation known as
'jar hell'.

Consider application A dependent on frameworks M and N, both of which
depend on a commons component X.

         A
         |
       -----
       |   |
       M   N
       |   |
       -----
         |
         X

Now consider what happens if framework M upgrades to a later version of
X, but N does not. The standard approach is to drop in X2 and hope that
N still runs.

         A
         |
       -----
       |   |
       M   N
       |   |
       -----
         |
        X2

However N may not run with X2 if the changes from X to X2 are major and
incompatible (which should be signalled via a major version change).

Given this situation, the application now has no simple options. They can:
a) give up and not upgrade framework M
b) petition framework N to upgrade
c) dive into the open source and upgrade N themselves
d) use two classloaders
e) use fancy bytecode weaving tricks to merge the versions
f) use jar embedding tools to alter N

I would argue that the majority of developers would choose option (a)
and give up. This is because while options b-f are possible, they are
not what the average *user* wants to spend their time doing.

Of course, all of this presents a very simple example. Most open source
stacks are much deeper than this and thus the potential for jar hell is
much higher.

The proposed solution is to rename the package of each commons component
at each major version change. This binds all the callers of the commons
component to a different package namespace, and thus no clashes, or jar
hell will ensue - except by human error.

Why now? Because this is the time that the majority of components are
starting to consider new incompatible versions, often related to JDK1.5.

DOWNSIDES:
- The client application has to change their package names when
upgrading to a later major version of the commons component.

- The client may get two versions of the same class in their IDE
autocomplete (most IDEs allow this to be filtered).


This proposal is about making upgrades *predicatable* at the expense of
a small amount of pain. I know that most of us don't really like it, but
I contend that there is no alternative other than to inflict pain on
users of commons over the next few years, and perhaps risk commons
becoming irrelevant by being unusable. I also strongly believe we need a
cross-commons approach on this.

Its perfectly possible for a component to have a major upgrade without
breaking backwards compatibility and I don't think we should mandate
this. Even when there is a break in backwards compatbility, then using
a deprecate / remove cycle should also be open as an option. There may
be a number of factors which influence the approach to take - how
widely used/depended on the component is, how major or minor the
in-compatibility is and how long / many versions the feature has been
deprecated before being removed/changed. This should be decided by the
component developers on a component by component basis and not
mandated as a policy.

There are clearly good reasons / circumstances to take the approach
you suggest, but it is a user unfriendly approach. As a user I like to
try out new versions by dropping in a new jar - before taking the
decision to upgrade. This approach rules that out and it wouldn't
surprise me if users started to see commons as irrelevant because of
"upgrade hell" if we take this route too often.

Niall


Stephen

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

Reply via email to