commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Henri Yandell <>
Subject Re: [all] Core library dependencies [was COLLECTIONS 3.3 release]
Date Sun, 10 May 2009 01:27:15 GMT
+1 on the low level libraries having no dependencies. C+P is a fine
way to share - we just, as Torsten points out, need to use smart ways
of C+Ping.

+1 to Stephen on backwards compat (which is probably surprising given
how much I argue with him on that subject).

I agree with it - but it frustrates me immensely due to the sheer
damage I think it does to a project. I'm of the opinion nowadays that
in a project there are two memes at war. Maintenance and Innovation.
Often it ends up with a fork, or the original author vanishes while
newer committers maintain ad infinitum (log4j being an example). It's
critical that a project/community find a way to blend both Maintenance
(Stability) and Innovation (Value), otherwise you end up where
Collections currently is. A dead end project heading nowhere.

Reaching that decision was the tipping point where I currently don't
care that Lang is not backwards compatible. I have no plans to ever
say +1 to Lang in its current state - the package names need changing
at a minimum - or if it feels enough like a different beast, the whole
name to being Lang2010. LangTNG. Core. Basic. SwissArmy (hmm... bet
that's trademarked :) ).

So...summarizing, and I think these are core tenets for the Commons
Core components (which by circular logic are those components that
abide by these tenets):

* No runtime dependencies beyond the platform they're targeted for
(ie: Commons JMS can depend on JMS).
* Backwards compatibility except when the API itself is a bug causing bug.
* A method by which we can innovate.

Currently we fail 100% on the third. I don't think we've found
anything that works. Changing Lang and making it non-backwards compat
isn't the 'right' way as Gump is off telling people there will be
problems and if it gets renamed to Bob, the old 2.x trunk is likely to
return as the lang/trunk.

That said - having a LangTwo branch inside Lang was also bad. Hard to
keep in sync while 2.4 then happened and too hidden away.

I'm wondering if the answer is a sandbox project. A plus side is that
it's more open to others working on it, and it has to go through a
defined promotion step, avoiding things like CLI2 becoming train


On Sat, May 9, 2009 at 2:23 PM, Stephen Colebourne
<> wrote:
> Yawn.
> Personally, I can't believe how hard it is to understand that dependencies
> for the core commons components are BAD. We're talking about [lang],
> [collections], [io], [codec] and probably a few others. For example,
> [functor] should be able to stand on its own two feet without needing to
> muscle its way in elsewhere. So should [id].
> (There are two types of library in commons - broad&shallow like lang,
> collections and io, and narrow&deep, like vfs, jelly or betwixt. The former
> should have no dependencies, the latter are no different to any other open
> source project and can have as many dependencies as the authors want.)
> These broad&shallow libraries are simply nothing like the kind of code
> normally worked on in day-to-day life. In our day jobs we simply don't write
> libraries like these, we consume them.
> There are lots of other big frameworks that understand the value of few
> dependencies and inlined code. Stripes and Wicket take a dim view of adding
> dependencies. Groovy has had similar discussions. I'm sure I could find many
> more. Its considered a *feature* - go read their docs. Here is the text from
> Stripes 1.4:
> "The removal of OGNL has significant benefits for users. Most obviously
> Stripes has one fewer dependency, which means easier installs and upgrades
> (Stripes is now down to two external dependencies)."
> If Stripes can do it, so can core commons.
> I could rail into a great big technical debate about why this is necessary,
> but it really should be obvious. These are the lowest of the low libraries.
> They are entrusted to us to take exreme care over as they are used by
> hundreds of thousands (maybe millions) of developers. Mess this up and its
> seriously bad.
> Using the argument that maven takes care of it is fallacious. You still
> can't escape jar-hell. Or the argument to create lots of smaller jars. Is
> that really what the *users* want?
> The key point is not really technical - its about remembering that the users
> are the real people who matter here. Do they want dependencies to save
> commons developers having to cut and paste one or two methods or classes?
> No. Absolutely not. I contend that it is a core selling point of these
> commons libraries that you can just pick one up and use it and have no other
> complications from dependencies to think of.
> Ask yourselves this question. Are there really any users of collectsion/lang
> that actually care whether there is one shared copy of MethodUtils or one
> for each jar? My answer is clear - those users don't care that collections
> needs method lookup utilities. Those users want collections!!! The details
> should be *encapsulated* and irrelevant!!!
> Put simply, every change that is made must be for the benefit of users, not
> commons-developers.
> A user choosing to include [collections] in their applications does so
> because they want collections! They are entitled and expect to make a
> separate choice as to whether to include [io] or [lang] entirely dependent
> on their needs. Note that this doesn't preclude creating link-jars, like
> [bean-collections], which are essentially new deliberately higher level
> projects (and should be managed as such really).
> Finally, the commons components aren't playthings that can be edited or
> changed around at will. So many people use them that each change needs to be
> considered with the greatest care. That is why I rail against the slightest
> backwards compatability issue, package change or dependency change.
> I speak from experience! In collections 3 I moved lots of classes between
> packages, with deprecations. This caused howls of derision and pain from the
> user community, and it is a lesson that until you experience it perhaps you
> won't understand.
> Of course, the result of my approach is that core broad/shallow commons
> libraries don't change much. *But thats the point*. They shouldn't change
> much. They need to be as dependable as there being food in the supermarket.
> I hope I've made my point. Sadly, I can't keep on writing down the reasons
> why adding dependencies or breaking backwards compatability is so bad. Maybe
> the only way to learn why this is so wrong is to make the changes and suffer
> the howls of derision that I once did. Unfortunately, doing so causes pain
> to hundreds of thousands of users, and I really want to avoid that.
> Stephen
> Ralph Goers wrote:
>> On May 5, 2009, at 11:15 PM, Jörg Schaible wrote:
>>> James Carman wrote at Mittwoch, 6. Mai 2009 03:12:
>>>> On Tue, May 5, 2009 at 6:36 PM, Matt Benson <>
>>>> wrote:
>>>>> I feel differently--how many times do we need to duplicate code that
>>>>> does
>>>>> the same damned thing amongst the various components?  For example,
>>>>> we've
>>>>> now added MethodUtils to [lang], but [collections] has its own set of
>>>>> code supporting InvokerTransformer.  [functor] doesn't have an
>>>>> analogous
>>>>> function because it seemed to me silly to keep rewriting and/or copying
>>>>> the necessary code.  IMHO we of the Commons need to establish an
>>>>> approach
>>>>> for "mixin" components, optional dependencies, svn externals,
>>>>> something,
>>>>> to avoid doing this again and again and again.
>>>> I'm with Matt on this one.  I really hate that Collections has its own
>>>> functors and I really hate having to copy code from one place to
>>>> another all the time.
>>>> I'd like to be able to keep my own little library of nifty functors
>>>> and use those throughout my application in different contexts.  Right
>>>> now, I have to use adapters all the time to go between one or the
>>>> other (functors vs. collections).  Yuck!  I've even gone as far as
>>>> creating little frameworky type classes that take these functor
>>>> classes (TransformerListCellRenderer and TransformerTreeCellRenderer
>>>> come to mind).
>>>> Perhaps we could split functors into an API jar and a utils or
>>>> algorithms jar?  The API would have all the main interfaces in it (the
>>>> stuff in org.apache.commons.functor).  Collections could depend on the
>>>> API and if folks want to use stuff from functor to do what they want,
>>>> then so be it.  If not, oh well.  The API itself really can't evolve
>>>> that much.  Those interfaces have been the same for a long time (other
>>>> than the generics)
>>> Maybe it's also time to think about more fine grained artifacts. With
>>> Maven
>>> the dependency management is no longer that worse. We could have
>>>  collections-x.y.jar
>>>  collections-functor-x.y.jar
>>> with the latter providing the stuff of collections depending on functor.
>>> This will not work for all kind dependencies between the commons stuff
>>> (e.g. helper classes from commons-io), but there are some components now,
>>> where an currently optional dep simply means additional functionality
>>> (e.g.
>>> in configuration or vfs).
>>> Opinions?
>> Well, it should be obvious that this seeming aversion to dependencies
>> isn't something I consider part of a good design. I've added several to both
>> configuration and vfs, all of which - as you pointed out - are optional. I
>> really don't understand the benefit of having mulitple copies of code in
>> various projects that will eventually get out of synch vs just sharing one
>> copy. I thought that was what commons was supposed to be all about.
>> OTOH, commons components should be fairly small so the number of
>> dependencies shouldn't get too out of hand.
>> Ralph
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail:
>> For additional commands, e-mail:
> ---------------------------------------------------------------------
> To unsubscribe, e-mail:
> For additional commands, e-mail:

To unsubscribe, e-mail:
For additional commands, e-mail:

View raw message