[jbossseam-issues] [JBoss JIRA] Commented: (JBSEAM-2973) EjbSynchronisations are destroyed before afterCompletion call

Torsten Fink (JIRA) jira-events at lists.jboss.org
Mon Dec 29 19:19:54 EST 2008


    [ https://jira.jboss.org/jira/browse/JBSEAM-2973?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12444232#action_12444232 ] 

Torsten Fink commented on JBSEAM-2973:
--------------------------------------

We probably stumbled over the same issue. 

Our application had to survive a night with full load. On the next morning the heap was full of JbpmContext's. After looking at the source code of Seam and at the debug messages we came up with this hypothesis:
* The SFSB EjbSynchronizations is placed in the event context, the Seam-JbpmContext-Component also lives in the event context.
*  Using EJB transactions, EjbSynchronizations is responsible for cleaning up the JbpmContext after the end of the transaction.
* Unfortunately the event context ends BEFORE EjbSynchronizations has the chance to clean up the JbpmContext.

Using BMT the transaction ends before the event context ends. Thus, the JbpmContext is cleaned up.

We switch all our MDBs, EJB-timers, and Web-services from CMT to BMT and (after fixing some other leaks, e.g. a class loader issue in jBpm), we survived the night.

I wrote a small test application that shows the memory leak, but I do not find a possibility to attach the archive. I uploaded the application to my personal account. You can find it here:

http://public.me.com/torsten.fink/

The name of the archive is "MemoryLeakEventKontext.tgz".

It is a Maven application that consists of
- a Web-GUI to start the test and displays the results
- a SFSB that sends 10 messages each to two queues (the standard queues A and B), waits a little bit, and does a gc
- two MDBs, one with CMT, one with BMT, which uses Seam injection to access a jBpm-Context
- an application scoped POJO that saves the contexts in a Set using a weak reference

After executing the tests and the GC, the surviving references are displayed. You can see that the CMT references are not gs'ed whereas the BMT references are cleaned up.



> EjbSynchronisations are destroyed before afterCompletion call
> -------------------------------------------------------------
>
>                 Key: JBSEAM-2973
>                 URL: https://jira.jboss.org/jira/browse/JBSEAM-2973
>             Project: Seam
>          Issue Type: Bug
>          Components: Core
>    Affects Versions: 2.0.1.GA
>         Environment: JBOSS4.2.2GA
>            Reporter: stefan meyer
>            Assignee: Pete Muir
>             Fix For: 2.1.0.BETA1
>
>
> http://www.seamframework.org/Community/EjbSynchronisationsAfterCompletionNotCalled
> I use an MDB. The EJBSynchronisations.registerSynchronisation are called by MangedPersistenceContext and ManagedJbpmContext. Thus creating 3 Synchronisation-Registration on the UserTransaction (first once is created by creating the ejb or maybe calling the create-method - dont know exactly). At some point the EJBSychronisations will be destroyed since they are stateful. Seam destroys them when calling Lifecycle.endCall and destroying the Contexts. The destruction will create another TransactionSynchronisation implemented by the StatefulRemoveInterceptor from Jboss. The beforeCompletion will be called in the order the synchronisations were registered. The afterCompletion will be called in the reverse order. The StatefulRemoveInterceptor is first and removes the EjbYnchronisation from the cache (whatever that is). The other calls fail because the ejb container cannot find them.
> My ugly workaround is to force a different order calling create and destroy of EJBSynchronisations upon entering the MDB. This leads to only one failure - the very first Synchronisations. 
> Reproducing this problem should be very straight forward. Just call an MDB and do sonething with the seam managed entityManager.
> Another bug closely related is that ManagedPersistenceContext.afterCompletion calls close. and in close it unsuccessfully tries to get a hold of the transaction component (Transaction.instance) - the contexts are gone already.
> here is the critical code (Please see the comment in afterCompletion):
>    public void afterCompletion(int status)
>    {
>       synchronizationRegistered = false;
>       //if ( !Contexts.isConversationContextActive() )
>       if (destroyed)
>       {
>          //in calls to MDBs and remote calls to SBs, the 
>          //transaction doesn't commit until after contexts
>          //are destroyed, so wait until the transaction
>          //completes before closing the session
>          //on the other hand, if we still have an active
>          //conversation context, leave it open
>          close();
>       }
>    }
>    private void close()
>    {
>       boolean transactionActive = false;
>       try
>       {
>          transactionActive = Transaction.instance().isActive();
>       }
>       catch (SystemException se)
>       {
>          log.debug("could not get transaction status while destroying persistence context");
>       }
>       
>       if ( transactionActive )
>       {
>          throw new IllegalStateException("attempting to destroy the persistence context while an active transaction exists (try installing <transaction:ejb-transaction/>)");
>       }
>       
>       if ( log.isDebugEnabled() )
>       {
>          log.debug("destroying seam managed persistence context for persistence unit: " + persistenceUnitJndiName);
>       }
>       
>       if (entityManager!=null)
>       {
>          entityManager.close();
>       }
>    }
>    

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: https://jira.jboss.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira

        



More information about the seam-issues mailing list