+ 1 with comments below

Carsten Ziegeler wrote:

Aren't you tired of implementing a service/dispose combo for each of
your components over and over again? Now, actually, I am. Big time.

If you look at several of our components, they do something like this:

class MyComponent implements SOMETHING, ThreadSafe, Disposable,
Serviceable {
protected ClassA compA;
protected ClassB compB;
protected ServiceManager m;

public void service(ServiceManager m) {
 this.m = m;
 compA = (ClassA)m.lookup(ClassA.ROLE);
 compB = (ClassB)m.lookup(ClassB.ROLE);
}
public void dispose() {
 if ( m != null ) {
   m.release(compA);
   m.release(compB);
 }
}

Way too much code me thinks. So what about:

class MyComponent implements SOMETHING, ThreadSafe {
 protected final ClassA compA;
 protected final ClassB compB;

 public MyComponent(ClassA a, ClassB b) {
   compA = a;
   compB = b;
 }
}

We could simply add constructor injection: if the implementation does
not provide a default constructor, the available constructor is called
using reflection and the components are injected on construction of the
object - no need to configure something in any xml configuration file.
Implementing this is easy - I did this already years ago for Fortress.

But I think it can even get easier:
1. Let's just assume that every component is ThreadSafe - unless
otherwise stated - no need to declare the interface anymore. I think
apart from the interpreter most components are threadsafe or poolable
anyway.

2. Let's remove support for pooled components - yes, seriously. Fiddling
with the pool sizes is really annoying. We have a working factory
approach for sitemap components, so why not simply use it overall? And
rewriting the remaining pooled components shouldn't be that hard. (I now
that we are proxying pooled components to simplify the lookup, but you
still have to configure pool sizes).
As my current experience is showing misconfigured pooling can be disastrous. However, when it is correct it is pretty fast. Before removing support for pooling lets actually prove that the factory approach performs approximately the same as the correctly configured pooled approach. Last time I checked there was exactly one factory component - the file generator. Can you do a quick test to show how that performs against the pooled version?

My final idea is to use even more magic (but it might be too much magic?):

class MyComponent implements SOMETHING {
 protected final ClassA component_A;
 protected final ClassB component_B;
}
When the component is instantiated all instance variables prefixed with
"component_" are setup using some injection mechanism - or perhaps using
annotations?

Now, in the end I really want to write less code :)

Ah and yes I'm talking about 2.2, seriously - I'll come up with a list
of things I think we should remove in 2.2 in the next days :)

Carsten