Stefano Bagnara wrote:
Bernd Fondermann wrote:

Stefano Bagnara wrote:

MailImpl objects have references to MimeMessageWrappers and are Disposable too. When we destroy MailImpls we call ContainerUtil.dispose(mail) or if you prefer we write this code:
--
if (mail instanceof Disposable) ((Disposable) mail).dispose();
--

[...]

2) This kind of pattern is used in many places in James: btw, how would you change it?


one strategy would be to make the current indirection even more indirect:

change ContainerUtils.dispose() so that it looks up a method dispose() on the parameter object and calls it, instead of typecasting.

then remove the Disposable interface from all James classes.


IMHO this is a step in the wrong direction.

The interface is not a limitation of James portability.

I'm -1 on removing our working interfaces in favor of reflections. THis is not good programming. I'm against bad practice to follow the POJO religion.


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.

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();

So, Disposable is a marker interface.

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?

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.

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 ;-) )

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.

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.

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


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.

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

  Bernd

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

Reply via email to