[seam-dev] Seam/jBPM integration within the SOA platform
Pete Muir
pmuir at redhat.com
Thu May 7 08:18:43 EDT 2009
Marek is going to work on this...
On 6 May 2009, at 15:08, Kevin Conner wrote:
> A few weeks back I was investigating a problem for a customer, related
> to the integration of seam applications within the SOA platform. I
> managed to chase down the issues but wanted to discuss them further in
> this forum. Apologies to Pete and Marek for taking so long over this.
>
> First the relevant configuration
>
> Within the SOA platform we have a jBPM/hibernate configuration that
> results in the use of the hibernate JTASessionContext to manage the
> lifecycle of sessions, tying those sessions into the encompassing JTA
> transaction. We are also using the jBPM JtaDbPersistenceService in
> order to guarantee the existence of a transactional context for the
> jBPM
> context.
>
> The codebase I have used in this investigation is from the following
> tag
>
> https://svn.jboss.org/repos/seam/branches/enterprise/JBPAPP_4_3_FP01
>
> When running a seam example on the SOA platform we were seeing an
> exception being thrown as a result of a hibernate session being used
> after it has previously been closed, this was a SessionException with
> the text "Session is closed!".
>
> In chasing this down I discovered two issues
> - an interleaving of the transaction synchronizations between jBPM
> and hibernate (now removed in jBPM, certainly in 3.2.5-SP5). This
> could cause the session to be closed twice, depending on which order
> the Synchronizations were invoked by the transaction manager.
> - hibernate objects being used outside of a transactional context
>
> It is the latter that I would like to understand further as I was
> surprised to see this given that some areas in the seam/jBPM
> integration
> explicitly test for the existence of transactions and even create a
> transactional context. Is there a reason why this is not completely
> done within a transaction?
>
> I appreciate that I am a seam novice and there may be something
> obvious
> that I am missing. I do have some suggestions for a fix, however, and
> would like some feedback as to whether they would be appropriate. I
> have attached the diff file to this message, again based on the
> previous
> tag.
>
> Thanks in advance for any help that you can give,
> Kev
>
> --
> JBoss, a Division of Red Hat
> Registered Address: Red Hat UK Ltd, Amberley Place, 107-111 Peascod
> Street, Windsor, Berkshire,
> SI4 1TE, United Kingdom.
> Registered in UK and Wales under Company Registration No. 3798903
> Directors: Michael Cunningham (USA), Charlie Peters (USA), Matt
> Parsons
> (USA) and Brendan Lane (Ireland)
> Index: src/main/org/jboss/seam/bpm/ProcessInstance.java
> ===================================================================
> --- src/main/org/jboss/seam/bpm/ProcessInstance.java (revision 10421)
> +++ src/main/org/jboss/seam/bpm/ProcessInstance.java (working copy)
> @@ -36,26 +36,16 @@
> {
> if ( !Contexts.isConversationContextActive() ) return null;
>
> - return new Work<org.jbpm.graph.exe.ProcessInstance>()
> + Long processId = BusinessProcess.instance().getProcessId();
> + if (processId!=null)
> {
> -
> - @Override
> - protected org.jbpm.graph.exe.ProcessInstance work() throws
> Exception
> - {
> - Long processId =
> BusinessProcess.instance().getProcessId();
> - if (processId!=null)
> - {
> - //TODO: do we need to cache this??
> - return
> ManagedJbpmContext.instance().getProcessInstanceForUpdate(processId);
> - }
> - else
> - {
> - return null;
> - }
> - }
> -
> - }.workInTransaction();
> -
> + //TODO: do we need to cache this??
> + return
> ManagedJbpmContext.instance().getProcessInstanceForUpdate(processId);
> + }
> + else
> + {
> + return null;
> + }
> }
>
> public static org.jbpm.graph.exe.ProcessInstance instance()
> Index: src/main/org/jboss/seam/bpm/ManagedJbpmContext.java
> ===================================================================
> --- src/main/org/jboss/seam/bpm/ManagedJbpmContext.java (revision
> 10421)
> +++ src/main/org/jboss/seam/bpm/ManagedJbpmContext.java (working copy)
> @@ -83,6 +83,12 @@
> throw new IllegalStateException("JbpmContext may only be
> used inside a transaction");
> }
>
> + if (jbpmContext == null)
> + {
> + log.debug( "recreating seam managed jBPM context" );
> + jbpmContext =
> Jbpm.instance().getJbpmConfiguration().createJbpmContext() ;
> + }
> +
> if ( !synchronizationRegistered && !Lifecycle.isDestroying()
> && transaction.isActive() )
> {
> jbpmContext.getSession().isOpen();
> @@ -100,7 +106,7 @@
>
> public void beforeCompletion()
> {
> - log.debug( "flushing seam managed jBPM context" );
> + log.debug( "closing seam managed jBPM context" );
> /*org.jbpm.graph.exe.ProcessInstance processInstance =
> ProcessInstance.instance();
> if (processInstance!=null)
> {
> @@ -113,47 +119,30 @@
> //destroyed, flush here:
> Contexts.getBusinessProcessContext().flush();
> }
> - jbpmContext.getSession().flush();
> - log.debug( "done flushing seam managed jBPM context" );
> + closeContext();
> + log.debug( "closed seam managed jBPM context" );
> }
>
> public void afterCompletion(int status)
> {
> synchronizationRegistered = false;
> - if ( !Contexts.isEventContextActive() )
> - {
> - //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
> - //event context, leave it open
> - closeContext();
> - }
> }
>
> @Destroy
> public void destroy()
> {
> - if ( !synchronizationRegistered )
> - {
> - //in requests that come through SeamPhaseListener,
> - //there can be multiple transactions per request,
> - //but they are all completed by the time contexts
> - //are dstroyed
> - //so wait until the end of the request to close
> - //the session
> - //on the other hand, if we are still waiting for
> - //the transaction to commit, leave it open
> - closeContext();
> - }
> + closeContext();
> }
>
> private void closeContext()
> {
> - log.debug( "destroying seam managed jBPM context" );
> - jbpmContext.close();
> - log.debug( "done destroying seam managed jBPM context" );
> + if (jbpmContext != null)
> + {
> + log.debug( "destroying seam managed jBPM context" );
> + jbpmContext.close();
> + log.debug( "done destroying seam managed jBPM context" );
> + jbpmContext = null;
> + }
> }
>
> public static JbpmContext instance()
> Index: src/main/org/jboss/seam/bpm/TaskInstance.java
> ===================================================================
> --- src/main/org/jboss/seam/bpm/TaskInstance.java (revision 10421)
> +++ src/main/org/jboss/seam/bpm/TaskInstance.java (working copy)
> @@ -36,25 +36,16 @@
> {
> if ( !Contexts.isConversationContextActive() ) return null;
>
> - return new Work<org.jbpm.taskmgmt.exe.TaskInstance>()
> + Long taskId = BusinessProcess.instance().getTaskId();
> + if (taskId!=null)
> {
> -
> - @Override
> - protected org.jbpm.taskmgmt.exe.TaskInstance work() throws
> Exception
> - {
> - Long taskId = BusinessProcess.instance().getTaskId();
> - if (taskId!=null)
> - {
> - //TODO: do we need to cache this??
> - return
> ManagedJbpmContext.instance().getTaskInstanceForUpdate(taskId);
> - }
> - else
> - {
> - return null;
> - }
> - }
> -
> - }.workInTransaction();
> + //TODO: do we need to cache this??
> + return
> ManagedJbpmContext.instance().getTaskInstanceForUpdate(taskId);
> + }
> + else
> + {
> + return null;
> + }
> }
>
> public static org.jbpm.taskmgmt.exe.TaskInstance instance()
> Index: src/main/org/jboss/seam/contexts/Contexts.java
> ===================================================================
> --- src/main/org/jboss/seam/contexts/Contexts.java (revision 10421)
> +++ src/main/org/jboss/seam/contexts/Contexts.java (working copy)
> @@ -18,6 +18,7 @@
> import org.jboss.seam.log.LogProvider;
> import org.jboss.seam.log.Logging;
> import org.jboss.seam.transaction.Transaction;
> +import org.jboss.seam.util.Work;
> import org.jboss.seam.web.Session;
>
> /**
> @@ -344,17 +345,32 @@
>
> //TODO: it would be nice if BP context spanned redirects
> along with the conversation
> // this would also require changes to
> BusinessProcessContext
> - boolean destroyBusinessProcessContext = !
> Init.instance().isJbpmInstalled() ||
> - !BusinessProcess.instance().hasActiveProcess();
> - if (destroyBusinessProcessContext)
> + try
> {
> - //TODO: note that this occurs from
> Lifecycle.endRequest(), after
> - // the Seam-managed txn was committed, but
> Contexts.destroy()
> - // calls BusinessProcessContext.getNames(),
> which hits the
> - // database!
> - log.debug("destroying business process context");
> - destroy( getBusinessProcessContext() );
> + new Work<Object>()
> + {
> + @Override
> + protected Object work() throws Exception
> + {
> + boolean destroyBusinessProcessContext = !
> Init.instance().isJbpmInstalled() ||
> + !
> BusinessProcess.instance().hasActiveProcess();
> + if (destroyBusinessProcessContext)
> + {
> + //TODO: note that this occurs from
> Lifecycle.endRequest(), after
> + // the Seam-managed txn was committed,
> but Contexts.destroy()
> + // calls
> BusinessProcessContext.getNames(), which hits the
> + // database!
> + log.debug("destroying business process
> context");
> + destroy( getBusinessProcessContext() );
> + }
> + return null;
> + }
> + }.workInTransaction();
> }
> + catch (final Exception ex)
> + {
> + log.warn("Exception destroying context ", ex);
> + }
> }
>
> if ( !Manager.instance().isLongRunningConversation() )
> Index: build/root.pom.xml
> ===================================================================
> --- build/root.pom.xml (revision 10421)
> +++ build/root.pom.xml (working copy)
> @@ -250,7 +250,7 @@
> <dependency>
> <groupId>org.jbpm</groupId>
> <artifactId>jbpm-jpdl</artifactId>
> - <version>3.2.2.GA_SOA-P</version>
> + <version>3.2.5.SP5</version>
> </dependency>
>
> <dependency>
> _______________________________________________
> seam-dev mailing list
> seam-dev at lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/seam-dev
--
Pete Muir
http://www.seamframework.org
http://in.relation.to/Bloggers/Pete
More information about the seam-dev
mailing list