On Fri, Jan 9, 2009 at 4:04 AM, Jim Knutson <knutson(a)us.ibm.com> wrote:
There's a similar problem on the @Init side as well. It appears
are specializing the init side to allow proper construction and
initialization, but are now ignoring the destruction side of the
Jim, I don't know what you mean by this.
Also, the initialization side seems to force constructor based
No, constructor injection is not supported for EJBs, unless the EJB
group decides to add support for this to the EJB spec (which is
looking increasingly slim in EJB 3.1 due to timelines).
This would require the container to order instance
construction and have pre-knowledge of instance initialization
data. This implies that there cannot be loops in the graph of
No, circularities can only occur for objects with normal scope types,
where the container can use a client proxy to break the recursion.
@Dependent scoped objects can't form circularities.
There is a pathological case where you have two beans with scope
@Dependent which both inject each other. This case results in an
infinite linked list of instances. However it occurs with any kind of
injection, not just constructor injection.
My first preference is that all bean instance creation / destruction
semantics be pushed to the EJB EG to deal with.
My second preference is that bean construction / initialization be
broken into 3 phases:
1) basic instance construction (i.e. JavaBeans null constructor / SFSB
2) dependency injection
3) business logic defined initialization
For EJBs, this is exactly the lifecycle. For simple beans we also
support constructor injection.
Step one should be used for the same reasons that the JavaBeans
spec. chose to use it. It frees tools / runtime to construct an
instance without foreknowledge of specialized constructor behavior.
Step two is separate because initializing state should be separate
from creating an instance. In this case, this is the container
managed portion of initializing state.
Hehe, I'll let you and Bob fight it out over this one!
In my view both approaches should be supported, if only because *some*
people disagree violently with what you just said :-)
(Not me, I don't care especially.)
Step three allows known patterns for initializing a bean to take
place. In this case, if there are known @Init methods that the
runtime can understand how to call, it should call them.
We don't support @Init methods, its part of the legacy EJB 2.x client
view, and we decided to only support the EJB 3.x client view.
This separation allows for customization to occur as the concept
of what a "bean" is expands.
I would expect a similar correlation of steps in reverse order
on the destroy side.
1) If there is a known @Remove method that the runtime can
understand how to call, it should call it.
2) Container/runtime state notifications occur on the instance
3) Destruction / GC of the instance
The gnarly things you are worried about in a @Remove method could
just as easily occur in a @PreDestory method.
No, I don't think so, because the @PreDestroy method is called *every*
time the bean is destroy, no matter which @Remove method was called.
Therefore, by nature, it can't do anything that shouldn't "always"
OTOH, the there are multiple @Remove methods, so no particular @Remove
method is called every time the bean is destroyed. There's no reason
to suppose that a @Remove method with no parameters is any different
from any other @Remove method on this respect.
The fact is that @Remove methods were designed to be called by the
client, not by the container.
special about either other than transaction (in the EJB case).
This brings up an important point. It may be necessary to perform
some DB operation at the end of the bean's life.
runs under an unspecified tran and is explicity stated as not to
be used for DB operations. If there's no @Remove invocation,
then there's no way to perform the necessary DB update.
Then it's going to be up to the application to call the @Remove method
before the context is destroyed.
Actually I really don't even want to think about the complexities of
transaction that kick off in the middle of the context destruction
phase of the request lifecycle. Ugh!