--- Stephen Colebourne <[EMAIL PROTECTED]> wrote: > Reply in-line, not terribly elegant as its after > midnight here ;-) > > From: "Rodney Waldhoff" <[EMAIL PROTECTED]> > > It may seem that I'm picking on [lang] here, but > that's not my intention. > > I just feel like I'm watching an impending > train-wreck, and intend to > > throw the switch while there's still time. > Or cause a fork to sourceforge. > > > The arguments in favor of monolithic components > I've seen seem to boil > > down to concerns about minimizing dependencies and > preventing > > circularities. > Partly, but I see it more about having a viable > community. [lang] has that > community, I don't believe 10 separate components > would.
Community is important, but consider that developers come and go. You want components that are conducive to focused development. If you do too much out-of-scope stuff, I think you risk alienating your future committers. > > 1) Monolithic components introduce false > dependencies. > Adding any dependency to your application adds a > risk, and you need to get a > reward for that risk. I would argue that adding more > dependencies (more > smaller jars, each with their own dependencies) > makes the overall situation > worse not better. But with smaller jars the average per-component dependencies become smaller. It's much easier to track and maintain the functionality you actually care about. > > 2) Monolithic components encourage superfluous > dependencies and > > inappropriate coupling. > > <snip> > > But when used infrequently in an otherwise > unrelated class, the price paid > > for this trivial reuse is fairly high, coupling > this code with a 1700+ > > line class to reuse 33 characters of code. (And > StringUtils uses > > CharSetUtils, which uses CharSet, which uses > various java collection > > classes, etc.) > This is actually a key point for the defence. If > this argument is followed > through, the logical conclusion is not to use > StringUtils, not to share > code, not to reuse. It is only if an application > uses a sufficient amount of > the functionality from any component that it will > choose to add the > dependency, rather than recode. If a component only > contains a couple of > classes people simply won't use it. I think it's more complicated than that. You actually should avoid adding a component dependency in your code if you need some trivial piece of functionality that's easily copied. I actually noticed you doing this earlier this week, which I thought was very good: http://marc.theaimsgroup.com/?l=jakarta-commons-dev&m=104059848924662&w=2 There are of course many circumstances where you actually should add dependencies. One is what you mention; when a component has a lot of functionality you plan to use. It probably doesn't make sense to copy code, even trivial code, in that case. Another equally important reason to add dependencies is when you're utilizing some non-trivial functionality. You don't want to copy and paste if you expect the underlying implementation to evolve. You can find prime examples of this throughout DBCP, Pool, HttpClient and Collections to name a few components. You can anticipate that HTTP clients will get more stable, FastHashMaps will get faster, etc. Base64 encoding, on the other hand, will not change very much at all. IMO the proposed Functor component also fits neatly into this category of evolving implementations. I'm concerned with trying to create a dependency-worthy component artificially by building up it with lots of useful but disconnected code. Frankly, if you have a small component and a user decides it's so trivial to implement that he simply cuts and pastes, that's a GOOD thing. Using a component as a code snippet library for minor functionality is totally legitimate in my view and a good way to keep your dependencies reasonable. > > 3) Monolithic components slow the pace of > development. > > > > When components are small and single purpose, > changes are small, > > well-contained, readily tested and easily > understood. New releases can be > > performed more readily, more easily and hence more > frequently. > I totally disagree with this. [util] languished for > over a year with no > action. No one took responsibility to promote, fix, > manage, look after or > release the code. This has now been noted on the > recent Jakarta PMC report I think util failed because it lacked that specific purpose. Size of the component is irrelevant. > > Releases take a significant amount of time. And > thats time away from coding, > bug fixing etc. 10 components means 10 times the > effort on releases, and I > simply do not accept that is viable. Bigger components take longer to release, so I don't think you're actually talking about 10 times as much effort. Smaller components can be released very easily as long as releases are frequent. I think that's one of the problems we have in Commons; we let components sit so long in development that the releases get more difficult than necessary. Everyone is eager to write new code and reticent to spend time stabilizing what they've already done; this is a natural impulse. I think that smaller specific components take no more effort to release in aggregate than that same code packaged up into one broader component. However, if there is increased technical debt but the result is higher quality and longer lasting components, I think it's worth it. > > Bundling unrelated code into a monolithic > component means I need to > > synchronize development of that unrelated code: > Maybe I'd like to do a new > > release of sub-component X, but I can't since > sub-component Y is in the > > midst of a major refactoring. Maybe I'd like to > do a major refactoring of > > sub-component A but I can't since sub-component B > is preparing for a > > release. > Virtually all the [lang] classes are fundamentally > independent, so > refactoring isn't an issue. And this actually > highlights that to be proper > about this would require a component for virtually > each class. I don't think that's true. The current code in lang has lots of potentially separable domains with substantial (and GROWABLE) implementations: functor, reflect, math, etc. The scope of lang seems to be stuff that should have been in the JDK. But that's how many good components start out. Technically, the JDK has Collections, HTTP connections, and JavaBean classes, but there was room for improvement. That's fuel for good, focused components. It's a proven strategy. > > 4) Monolithic components make it more difficult > for clients to track and > > communicate their dependencies. > Maybe you place more store in version numbers than I > do. If I pickup any new > jar, I'd test it whatever the version number > difference. That doesn't mean the effort is wasted. > > 5) Monolithic components only hide circularities, > and may even encourage > > them. > Perhaps it does. But it allows us to actually > develop code without arguing > about which should depend on which all the time, and > that is terribly > wasteful. Depends on who you ask. I'd hesitate to depend on code that I thought was out-of-scope for the component. > > 6) Monolithic components only get bigger, making > all of these problems > > worse. > > > > For instance, the [lang] proposal that was > approved describes its scope > > as: > > > > "[A] package of Java utility classes for the > classes that are in > > java.lang's hierarchy, or are considered to be so > standard as to justify > > existence in java.lang. The Lang Package also > applies to primitives and > > arrays." [6] > I agree that the proposal does not fully define > [lang] anymore. Nor does the > name. > > "A component of Java utility classes to supplement > those provided in the JDK > java.lang and java.util package hierarchies. The > component also applies to > primitives and arrays. The component shall depend > only on the JDK." And there are functors, and there is math, and there is serialization, and there are Java implementations of C structures. And why is "[t]he component shall depend only on the JDK" part of the scope? I don't want to pick on lang specifically, and I don't suggest that components can't grow and evolve. However scope changes should be made deliberately, visibly and sensibly. > > In the five months since that proposal was > accepted, the scope of lang has > > expanded significantly ([7], [8], [9], [10], [11]) > and now includes or is > > proposed to include: > > > > * math utilities [12] > > * serialization utilities [13] > > * currency and unit classes [14] > > * date and time utilities [15] > > * reflection and introspection utilities [16] > > * functors [17] > > * and much more [18], [19], [20], [21], [22] > > > > And the more the scope expands, the more the scope > expands--the existence > > of the [lang] monolith has encouraged a reduction > in ([23], [24], others) > > and discouraged the growth of ([25], [26], others) > other components, and > > has discouraged the introduction of new components > ([27], [28], others). > Or viewed alternately, [lang] has had the community > to grow and stay active > while other components have not. Not all of the > ideas presented in the list > above will end up in [lang] (some get rejected). > Many should though, as they > provide functionality that the JDK should provide - > and thats what [lang] is > about. I think good long-term components descibe a specific domain: HTTP requests, pools, Collections, math, reflection, etc. etc. etc. "Functionality that the JDK should provide" is a pretty wide net. > > As above and before, if classes aren't commonly > used, changed, and > > released together, or mutually dependant on each > other, they should be in > > distinct components. If we want a catch-all JAR, > we've got one [3]. > > Given the principles enumerated in the commons > guidelines and detrimental > > effects enumerated here, I'm not sure why we'd > follow any other course. > Because open source is about community first, code > second. As a group of > functions, [lang] has ideas, momentum, growth and > life. As a small isolated > component (in line with commons guidelines), [util] > and [pattern] have both > died through lack of interest. > > Stephen I think they died from lack of focus: http://marc.theaimsgroup.com/?t=102504081900002&r=1&w=2 I thought that the 1.0 version of lang was a pretty coherent package that mainly did supplement java.lang classes as advertised. I'm concerned that it's now moving in so many different directions without definition. I've been careful not to be discouraging of a lot of the recent proposals even though I felt them out of scope, mainly because I'm not a lang developer and I don't want to interfere. However, I do believe that lang is becoming rather monolithic. I'm also concerned that the functor package was not approved when it's both worthy of a separate component and out of scope in lang. I'm really surprised that you don't see the benefits of a visible functor package, rather than burying the code in lang. I think it would get much more interest on its own. I'm also a little surprised that functor only got two positive votes. Robert asked for a formal vote so he could support it, but then he never actually cast that crucial vote. Tsk, tsk. He must have been waylaid by bandits. :) - Morgan ===== Morgan Delagrange http://jakarta.apache.org/taglibs http://jakarta.apache.org/commons http://axion.tigris.org http://jakarta.apache.org/watchdog __________________________________________________ Do you Yahoo!? Yahoo! Mail Plus - Powerful. Affordable. Sign up now. http://mailplus.yahoo.com -- To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>