I have a question about bean pooling. Suppose the EJB container helps an EJBObject reclaim its bean (which is now serialized because the live bean instance was stolen from this EJBObject by another EJBObject during inactivity). When the serialized version of the bean is deserialized, a new instance of the bean is created, even though its state represents that of a bean which previously existed.
My question is this: What does the container do if the number of bean instances now exceeds (by virtue of the new instance created during the deserialization process) the number of like beans allowed? I know this is an implementation issue and, therefore varies among differing implementations, but please think about it anyway.
One guess is that the EJBObject/container dynamic duo steal a bean from some other EJBObject (which is currently inactive) and throw the stolen bean away (remove any reference to it and therefore make it vulnerable to garbage collection) once the serialized bean is deserialized.
An alternative is that the container could allow the EJBObject to cheat and keep the newly serialized bean (althought the max count is violated) until the method invocation is complete, at which point the EJBObject would reserialize the bean and throw away the live instance. While the second option allows the container/EJBObject to avoid stealing a bean, it nonetheless could allow the bean count limit to be greatly surpassed.
This question might be silly and I imagine someone will tell me if it is ("you don't have to know how the container is implemented to use EJB", etc ...) but I do believe that the question merits some thought. I thank you for thinking about it.
I'm not sure I understand your question. Stateful session beans are serialized, but not pooled. Entity beans, stateless session beans, and message-driven beans are pooled but not serialized. This of course is an implementation detail, but it is practically forced by the EJB spec. As far as I know this is the way EJB is implemented in most App servers.
Can you repeat the question, bearing this in mind?
You are correct. I appologize for having used the term improperly. I am referring to the contents of the section "Achieving the Effect of Pooling with Stateful Beans" in Chapter 4 of Ed Roman's book "Mastering Enterprise JavaBeans". Even if I used the term pooling improperly, however, perhaps the remainder of the post might make sense.
I understand that serialization doesn't happen following each invocation of a stateful session bean's method. Were we to allow the container to instantiate two beans and there happened to be only two clients invoking methods on the servant instances (which implement some sub-interface of EJBObject,) then each of these servants could keep the bean to which it is attached; there would be no contention. If, on the other hand, the relevant home object has dispensed five stubs to five different clients, then the five servants (assuming one servant gets exported for each stub issued) will contend for two beans. This, I believe, is when serialization happens. If a servant is not currently invoking a method on the bean to which it is attached, then that bean can be stolen by another servant. Because the bean is stateful, it must be serialized to record its state. First, the bean's ejbPassivate method is called. Then the bean is serialized. Following the it's serialization, the bean is then made fit for the new servant. If the servant who just stole this bean was mid-conversation with it's client, then it must make the state of the new bean identical to the state of the bean at the time of the last method invoked (on both it and the bean) by the client. So, it deserializes the bean which reflects that conversational state and, in so doing, creates a new instance of a bean (by virtue of the serialization). Now, there are three bean instances. What does the container do to reduce the number of bean instances? Even if serialization might be forced on the container vendor, the action taken when the number of bean instances exceeds the number of bean instances allowed is totally up to the vender. Nonetheless, it is a good exercise to think about.
I thank you for having responded to the first question. If you made it through the second post, I am truly grateful. If you have given up on my question, I will understand.
I think the term "pooling" doesn't exactly fit in this situation, and that might be what is causing the comfusion. When we pool a resource, that implies that it can be used by several consumers (perhaps not at the same time). This is the case for entity beans, for instance. The container can use the ejbActivate and ejbPassivate callbacks to "switch" the beans identity and make it represent a different physical entity. So, in effect, a single instance can be used to represent several entities (not at the same time), and can thus be said to be pooled.
The ejbActivate and ejbPassivate callbacks on session beans are quite different, and similarity of the names is probably a poor choice (as some of the EJB expert group admitted). The container can't use an instance to represent several different sessions, like the entity bean analogy might suggest. What it can do, and does do, is decrease the number of beans *in memory* by passivating ones that are not being used extensively, using an LRU or similar strategy.
The container must allways have a distinct instance of each session bean in the system. That instance may or may not be serialized, but it's still a distinct instance. A session bean stub can't "steal" a session bean instance, simply because it has no way of "switching" the state of the existing instance. All it can do it use it's existing loaded instance, or load the instance from it's serialized state and then use it. It's actually very simple, much simpler than entity bean interaction patterns. The only thing that might resemble the "stealing" effect is that activating one instance may mean passivating a different instance, according to some strategies (ones placing an upper bound on the number of instances). In that sense, the answer to your question might be "it passivates a different instance". But again, the pooling analogy is very weak.
I hope that helps to clear this issue. If it still doesn't, don't give up on me :)
Thank you for not having given up on me. That last explanation answered THE root question. Thank you again!