5 Replies Latest reply on May 29, 2009 3:15 PM by rlperry

    MDB calling a session bean, session bean not getting reused

      Hello,

      I have an MDB that does a lookup on a stateless session bean, calls some method on the session bean and returns. The MDB and the SLSB are running in the same EJB container.

      However, everytime an MDB looks up the SLSB, a new instance of the bean is created instead of using the available beans.

      I have observed this using the jmx-console application running in JBoss. By choosing the SLSB (JMX Bean View) and observing the Available Count, Create Count and Current Size properties.

      I am seeing that even when the beans are available, every lookup request from the MDB is resulting in a new bean getting created. (Also the bean creation does not obey the MaxSize property).

      On a side note, I don't see this behavior when one SLSB looks up another SLSB. The beans are re-used in this case.

      Is there a particular way to consume SLSBs from MDBs? Do I have to explicitly release them?

      Any help would be appreciated.

      JBoss 5.0.0.0CR2
      RHEL4 & Windows XP

      Thanks,

      Shreyas

        • 1. Re: MDB calling a session bean, session bean not getting reu
          ryanrlamothe

          This is the EXACT behavior we have been observing as well, in JBossAS 4.2.2, which we have been trying to figure out how to work-around.

          We have observed that any stateless session bean called from an MDB is never released or any SLSB called from those SLSB's down the line.

          • 2. Re: MDB calling a session bean, session bean not getting reu

            I have a nice little reproducible test case to see this behavior but I don't know how to attach it to this posting.

            Thanks,

            Shreyas

            • 3. Re: MDB calling a session bean, session bean not getting reu
              ryanrlamothe

              I wanted to post some follow-up information, in case anyone had any additional thoughts. This appears to be a bug in multiple versions of JBoss AS, including apparently 5.0, where any time a stateless session bean is injected into an MDB a new instance of that stateless session bean is created, but never removed from the thread pool. Therefore, if an MDB makes 500 calls to a SLSB, the container will end up with 500 instances of that SLSB which never get removed. This could potentially be the source of a major memory leak.

              So, after some digging, the following information pointed to the ability to force the SLSB's into a pool of a specific maximum size:
              http://www.jboss.org/jbossejb3/docs/reference/build/reference/en/html/session-bean-config.html

              Which worked, for the specific SLSB which you annotated to use that pool, but unfortunately each subsequent SLSB that was called from that initial SLSB would still display the original behavior. Now, adding that annotation to every single bean individually down the stack did not seem like a great idea either, although it could be done if required. But the idea of controlling the pool was interesting, which lead me to research this more, and I came up with the following information:

              https://jira.jboss.org/jira/browse/JBAS-5345 (BUG Report!)
              http://www.jboss.org/index.html?module=bb&op=viewtopic&t=132763
              http://www.jboss.org/index.html?module=bb&op=viewtopic&t=132331

              Long story short:

              - EJB3 annotations are intercepted using JBoss AOP and are configured in "default/deploy/ejb3-aop-interceptors.xml". So, instead of annotating each SLSB individually, we can provide a blanket solution at this point to all SLSB's.

              - ThreadlocalPool isn't very strict, apparently, but StrictMaxPool appears to give us the behavior we want

              - As noted by wolfc in the first forum thread...It would appear that JBossMQ does not use a ThreadPool, but instantiates threads on the fly. Thus the ThreadlocalPool will keep on creating instances to match. That makes the use of StrictMaxPool mandatory. Which is the behavior we are seeing.

              To put all of this to the test, all of the Stateless Bean domain annotation expressions in ejb3-aop-interceptors.xml where changed from:

              @org.jboss.annotation.ejb.PoolClass (value=org.jboss.ejb3.ThreadlocalPool.class, maxSize=30, timeout=10000)


              to

              @org.jboss.annotation.ejb.PoolClass (value=org.jboss.ejb3.StrictMaxPool.class, maxSize=30, timeout=10000)


              Note: The MDB domain annotation expressions use StrictMaxPool by default!

              This appears to solve the problem, but will require more monitoring in the coming weeks. Any other thoughts on this issue? Concerns about contention in the StrictMaxPool? Thoughts on another, better solution?

              Thanks!

              • 4. Re: MDB calling a session bean, session bean not getting reu

                I am coming across this problem in EJB 2. Any idea how to fix this issue with EJB 2 on Jboss 4.2.2 GA?

                • 5. Re: MDB calling a session bean, session bean not getting reu
                  rlperry

                  I have this problem with ActiveMQ and had been having pretty good luck with StrictMaxPool, but in doing some testing with ThreadLocalPool, I learned that my problem resolves back to the JCA thread pool. Basically as long as I am keeping the server completely busy I do not leak Session Beans, but when the server goes idle the JCA threads are deallocated, but the associated Stateless Beans are not. So when the server gets busy again all new instances of my beans are created.

                  I am now working around this by setting MinimumPoolSize =MaximumPoolSize in jbossjca-service.xml. For my application I really sorta like this configuration anyway.

                  So for me the only question is how do we get deallocations when threads go away?