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 <gudnabr...@yahoo.com>
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: dev-unsubscr...@commons.apache.org
For additional commands, e-mail: dev-h...@commons.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@commons.apache.org
For additional commands, e-mail: dev-h...@commons.apache.org