commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Stephen Colebourne <>
Subject [all] Core library dependencies [was COLLECTIONS 3.3 release]
Date Sat, 09 May 2009 21:23:34 GMT

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 

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 

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.


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:

View raw message