2 Replies Latest reply on Jan 10, 2012 9:13 AM by Daniel Lechner

    Memory Leak when calling @Destroy (with SFSBs)

    Daniel Lechner Novice


      I've discovered a memory leak in our application and I think it is a bug in Seam. Here we go:

      We're using Seam 2.2.2.Final deployed in an EAR on JBoss AS 5.1.0.GA.

      In an example-project, we have 2 Seam components, one POJO and one SFSB. The POJO-component uses the SFSB-component via Seam-DI (@In). The POJO-component has a method annotated with @Destroy.

      We are using the POJO-component in a (long-running-)conversation. Thus, the TestComponentA as well as the TestEJB will be created.
      When the conversation is ended and all components will be removed, the @Destroy-methods of all seam-components are called one after each other. The order, the @Destroy-methods are called, depend on the hashCode of the seam-name of the components (the component-names are put into an java.util.HashSet in the method org.jboss.seam.contexts.ServerConversationContext.getNamesFromSession() - the for-loop of the method org.jboss.seam.contexts.Contexts.destroy iterates over this HashSet afterwards).

      In the following example, the component-names have been chosen in this way, that the TestEJB will be removed before the TestComponentA is removed. So see the call-sequence:

      1. the SFSB-component is destroyed by seam - the container removes the SFSB

      2. the @Destroy-method of the POJO-component is called. But before, Seam-DI creates a new SFSB-component TestEJB because of the @In-annotation

      3. the POJO-component is removed by the GC

      4. the SFSB-component is still present

      It is easy to see that there are unused SFSBs via the jmx-console or in the server-log:

      10:56:31,693 ERROR [STDERR] TestEJB.postConstruct() called
      10:56:31,693 ERROR [STDERR] tca created
      10:59:36,518 ERROR [STDERR] TestEJB.discard() called
      10:59:36,518 ERROR [STDERR] TestEJB.preDestroy() called
      10:59:36,519 ERROR [STDERR] TestEJB.postConstruct() called
      10:59:36,519 ERROR [STDERR] tca destroyed

      To reproduce the bug, 2 simple Components have been created. This is the SFSB-Component:

      public class TestEJB implements TestEJBLocal
          public static final String SEAM_NAME = "tcb";
          public void discard()
              System.err.println("TestEJB.discard() called");
          public void postConstruct()
              System.err.println("TestEJB.postConstruct() called");
          protected void preDestroy()
              System.err.println("TestEJB.preDestroy() called");

      ...and it's local-interface:

      public interface TestEJBLocal
          /** The local JNDI name for this EJB. */
          final static String JNDI_NAME = "ejb/project/TestEJB/local";
          public void discard();

      Last but not least the POJO-Component:

      public class TestComponentA implements Serializable
          public static final String SEAM_NAME = "tcd";
          private static final long serialVersionUID = 7550180731244593255L;
          private TestEJBLocal testEJB;
          public void create() {
              System.err.println("tca created");
          public void destroy() {
              System.err.println("tca destroyed");