views:

1057

answers:

2

Our years-old WebLogic J2EE application has a message-driven bean which makes use of a stateless session bean. The MDB onMessage method gets the home interface of the stateless session bean and calls the home interface's create() method to get the actual stateless session bean itself.

The code does not attempt to cache the session bean, just uses it directly:

public void onMessage(Message message) 
{
    ...
    MySessionBeanLocal ejbLocal = MySessionBeanLocalHome.create();
    ejbLocal.myMethod();

There is no corresponding remove() call in the MDB.

My question is: is it bad not to be calling remove() in this case?

I'm fairly sure that one is required to call remove() for a state*ful* session bean, but it's less clear to me if the remove() call is necessary for state*less*.

We recently made significant performance improvements but suddenly began to run out of stateful session beans under load with this exception:

java.lang.RuntimeException: An invocation of EJB MyMessageDrivenBean(Application: MyApplication, EJBComponent: MyApplication.jar) timed out while waiting to get an instance from the free pool. at weblogic.ejb20.pool.StatelessSessionPool.waitForBean(StatelessSessionPool.java:229) at weblogic.ejb20.pool.StatelessSessionPool.getBean(StatelessSessionPool.java:100) at weblogic.ejb20.manager.StatelessManager.preInvoke(StatelessManager.java:140) at weblogic.ejb20.internal.BaseEJBLocalObject.preInvoke(BaseEJBLocalObject.java:228) at weblogic.ejb20.internal.StatelessEJBLocalObject.preInvoke(StatelessEJBLocalObject.java:53) at MyMessageDrivenBean_x56omo_ELOImpl.processMessage(MyMessageDrivenBean_x56omo_ELOImpl.java:28) at MyMessageDrivenBean.onMessage(TBMessageListener.java:94) at weblogic.ejb20.internal.MDListener.execute(MDListener.java:370) at weblogic.ejb20.internal.MDListener.onMessage(MDListener.java:262) at weblogic.jms.client.JMSSession.onMessage(JMSSession.java:2678)

Our MDB pool is set to:

<message-driven-descriptor>
<pool>
    <max-beans-in-free-pool>20</max-beans-in-free-pool>
    <initial-beans-in-free-pool>5</initial-beans-in-free-pool>

Our stateless session bean pool is set to:

<stateless-session-descriptor>
<pool>
     <max-beans-in-free-pool>50</max-beans-in-free-pool>
     <initial-beans-in-free-pool>5</initial-beans-in-free-pool>

My question is, is the MDB that calls create() on the stateless session bean also responsible for calling the remove() for the state*less* session bean as well? (The application seems to have run for years without calling remove(), but I'm wondering if improved throughput has exposed an old bug.)

A: 

The remove() method would be called anyway after the remote interface object is garbaged. I think no EJB application should obligate explicitly calling the remove() methods, if that happens, it's probably because the pool is too small. Of course you call always using for fine-tunning, but this should be an exception, not the rule.

razenha
A: 

@christophergraz

Did yo find a soln to your problem. I am using ejb3 and after the onMessage() executes the stateless session beans are never sent back to the bean pool. They stay in memory and evetually cause the server to crash.

Sorry, in my case the problem turned out to be some bad code someone checked in. We resolved by rolling back the change, so this question became moot for me.I guess razenha has provided the best answer; I'm just not in a position to validate his answer right now. :-P
christophergraz