Bernd Fondermann wrote:
mmhh. I am religiously against religion in programming, too. ;-)
Earlier you proposed to get rid of abstract discussions like POJO vs. Avalon. At least, please don't put me in a corner. This is only for discussion.

Sorry Bernd, I didn't want to put you in a corner :-)

On the interface topic:

Some James code forensic:
Disposable declares one method with no arguments, dispose().
There is no single variable declared of type Disposable.
Instead, all current uses of Disposable are

    if (obj instanceof Disposable) (Disposable) obj).dispose();

and could very well be replaced by ContainerUtil.dispose();

Most of James should use ContainerUtil instead of the instanceof. I change the "instanceof" method with the ContainerUtil call each time I work on a james object :-).

So, Disposable is a marker interface.

Exactly.

AFAIK, there is no enforcement of calling dispose() for Disposable objects which are not handled by Avalon itself through a central lifecycle handler or something alike.

Who knows if Disposable instances really are disposed? Or if the class I am calling ContainerUtil.dispose() on is really disposable?

Exactly we can't be sure this will happen. It is simply a contract.
Also in SDI IoC you can't be sure that your dependencies will be followed.
The lifecycle methods, by their nature, are only a contract and it is left to the container to call them.

So all the interface says is: This class is ready/expecting to be disposed. (Which is ok.) But if you read: "This class will get disposed" you are on the wrong track. The class contract would promise you something the application can not hold.

Ok, but this is really a common issue in ANY container. I still don't get the point. If you don't expect the container and your code to do what it is supposed to do then you could even expect it could even not start your application :-)

Pls take a look at the instance variable
    Mail mail
in SMTPHandler.
interface Mail extends Serializable, Cloneable (not Disposable)

SMTPHandler receives a Mail instance and at some point calls dispose().
But if it does not get a MailImpl (implementing Disposable) but some other implementation (not implementing Disposable)?
Nothing happens. (Which is: bad things happen ;-) )

@SMTPHandler:417

if (mail instanceof Disposable) {
        ((Disposable) mail).dispose();
}

So if the Mail is not a MailImpl and does not implement disposable won't be disposed. And this is GOOD thing.
I don't see where the bad things happen: the mail will be garbage collected.
It seems to me an acceptable contract: you send me disposable stuff I dispose it, otherwise not.

Furthermore, this kind of lifecycle on "non top level objects" cannot be delegated to the container. So James have to manually manage the lifecycle of that objects (mails for example).

Can you explain me how it can work better with no "Disposable" interface?

[note to me: remember to change it to ContainerUtil.dispose(mail)]

The use of lifecycle marker interfaces tries to improve the 'overall contract' of a class in a specific container environment on one hand but is hindering class reuse on the other hand.

I don't see how an interface limit an object in any way.
Can you tell me something you can do on the object not implementing Disposable that you cannot do on the object implementing Disposable? As you said, Disposable is a marker interface, you can think at it as something similar to a marker annotation.

On topic reflection:
I really don't see why using reflection is a bad thing compared to the current cast-to-call invocation of Disposable. They seem more or less equivalent.

1) reflections reduce the code browsability.
2) if I use a third party object that implement a dispose method called by itself in its own lifecycle and not intended to be called by me (or the avalon container) I would do the wrong thing. 3) you can use reflections also with the Disposable interface there, but you can't do the opposite.

James currently already uses dynamic invocation, so this is no big deal, isn't it? (Or do you think that should be removed eventually?)

The fact that we already have possible bottlenecks is not a good reason to introduce new ones :-)

Can you list the advantages of removing the Disposable interface?
Here is the only one I see:

1) reduce the size of James by 162bytes (the size of the Disposable.class) + something like 40 bytes for each implementing object. Maybe 2Kb in total.

Any other pro?

for example, a container could be configured to call the dispose() method declarative where Avalon uses Disposable casts.
pseudocode: <component class="X" onDestroy="dispose" />
(while dispose calls from within James still use the ContainerUtils-approach.)

We can do this without removing the Disposable interface.

Probably, but it will always get in your way.

Again, these are just thoughts to comparing the current approach to things Spring framework or XBean are doing. Everyone with its strengths and weaknesses.

I never read that Spring and XBean suggest to remove interfaces from objects. In fact I always thought that Spring/XBean and "current approach to things" was programming against interfaces and "leave the reflection job to the container".

And, I'd still prefer to put a release out _before_ starting any branches for container replacement.

  Bernd

I agree.
Stefano


---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to