<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<body link="#355491" alink="#4262a1" vlink="#355491" style="background: #e2e2e2; margin: 0; padding: 20px;">
<div>
        <table cellpadding="0" bgcolor="#FFFFFF" border="0" cellspacing="0" style="border: 1px solid #dadada; margin-bottom: 30px; width: 100%; -moz-border-radius: 6px; -webkit-border-radius: 6px;">
                <tbody>
                        <tr>
                                <td>
                                        <table border="0" cellpadding="0" cellspacing="0" bgcolor="#FFFFFF" style="border: solid 2px #ccc; background: #dadada; width: 100%; -moz-border-radius: 6px; -webkit-border-radius: 6px;">
                                                <tbody>
                                                        <tr>
                                                                <td bgcolor="#000000" valign="middle" height="58px" style="border-bottom: 1px solid #ccc; padding: 20px; -moz-border-radius-topleft: 3px; -moz-border-radius-topright: 3px; -webkit-border-top-right-radius: 5px; -webkit-border-top-left-radius: 5px;">
                                                                        <h1 style="color: #333333; font: bold 22px Arial, Helvetica, sans-serif; margin: 0; display: block !important;">
                                                                        <!-- To have a header image/logo replace the name below with your img tag -->
                                                                        <!-- Email clients will render the images when the message is read so any image -->
                                                                        <!-- must be made available on a public server, so that all recipients can load the image. -->
                                                                        <a href="https://community.jboss.org/index.jspa" style="text-decoration: none; color: #E1E1E1">JBoss Community</a></h1>
                                                                </td>
                                                        </tr>
                                                        <tr>
                                                                <td bgcolor="#FFFFFF" style="font: normal 12px Arial, Helvetica, sans-serif; color:#333333; padding: 20px; -moz-border-radius-bottomleft: 4px; -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 5px; -webkit-border-bottom-left-radius: 5px;"><h3 style="margin: 10px 0 5px; font-size: 17px; font-weight: normal;">
Concurrency problems with JBPM 5.4
</h3>
<span style="margin-bottom: 10px;">
created by <a href="https://community.jboss.org/people/jkranes">Jon Kranes</a> in <i>jBPM</i> - <a href="https://community.jboss.org/message/828867#828867">View the full discussion</a>
</span>
<hr style="margin: 20px 0; border: none; background-color: #dadada; height: 1px;">
<div class="jive-rendered-content"><p><span style="font-size: 10pt; font-family: Arial, sans-serif;">I am working on a JBPM 5.4 / jBoss 7.1.1 application and have been unable to get it to run reliably using multiple threads.</span></p><p style="min-height: 8pt; height: 8pt; padding: 0px;"> </p><p><span style="font-size: 10pt; font-family: Arial, sans-serif;">The basic approach I am taking is as follows:</span></p><p style="min-height: 8pt; height: 8pt; padding: 0px;"> </p><ul style="list-style-type: disc;"><li><span style="font-size: 10pt; font-family: Arial, sans-serif;">Process instances are triggered by an incoming message (AMQP/ RabbitMQ) received by a message listener.  For optimal performance I need to be able to use multiple listener threads.   (Ultimately there will be multiple application server host instances as well but first things first).</span></li><li><span style="font-size: 10pt; font-family: Arial, sans-serif;">I am creating a new StatefulKnowlegeSession for each new ProcessInstance.</span></li><li><span style="font-size: 10pt; font-family: Arial, sans-serif;">I am using a local HumanTaskService (note that I am able to trigger concurrency problems mentioned below even while using a workflow that has no user tasks in it).<br/></span></li><li><span style="font-size: 10pt; font-family: Arial, sans-serif;">I am disposing of the session and its associated handlers immediately after starting the process.  If I need to respond to an asynch signal (e.g. completion of a human task) I create the session by ID from the database (this is part of the scaling strategy - need to be able to continue the process at a future time on an entirely different machine).</span></li><li><span style="font-size: 10pt; font-family: Arial, sans-serif;">Mainly using Oracle (11g XE) but have also tested with MySQL and see the exact same issues.<br/></span></li></ul><p style="min-height: 8pt; height: 8pt; padding: 0px;"> </p><p><span style="font-size: 10pt; font-family: Arial, sans-serif;">I am using Spring with declarative transactions.  I am using JTA transactions through the jBoss platform JTA transaction manager.</span></p><p style="min-height: 8pt; height: 8pt; padding: 0px;"> </p><p><span style="font-size: 10pt; font-family: Arial, sans-serif;">Here's what I am experiencing:</span></p><p style="min-height: 8pt; height: 8pt; padding: 0px;"> </p><ul style="list-style-type: disc;"><li><span style="font-size: 10pt; font-family: Arial, sans-serif;">Everything works fine as long as as I run a single thread only (i.e. have only one instance of my message listener class).  I can run this way for hours without a single exception being thrown.</span></li><li><span style="font-size: 10pt; font-family: Arial, sans-serif;">With two or more message listeners, I get exceptions (not necessarily right away, but if I run enough iterations it happens pretty quickly).</span></li><li><span style="font-size: 10pt; font-family: Arial, sans-serif;">I see a variety of different exceptions each time I run the program.  The exceptions vary but all are related to inability to commit, invalid sessions, inability to find a certain piece of data (the session or process instance), deadlocks, concurrent modification exceptions, etc.  All the kinds of things you would expect in non threadsafe code.</span></li><li><span style="font-size: 10pt; font-family: Arial, sans-serif;">Once an exception is thrown on a given thread, it seems that the thread will just keep throwing the 'Entity Manager is Closed' exception.  I am guessing there is something happenging here with a ThreadLocal tied to the thread that never gets cleared up once problems occur on that thread.  If I run long enough, all threads end up with this problem and the system basically becomes useless and needs a full restart.<br/></span></li></ul><p style="min-height: 8pt; height: 8pt; padding: 0px;"> </p><p><span style="font-size: 10pt; font-family: Arial, sans-serif;">So without trying to debug each and every exception one at a time, I'm wondering if there is anything obvious I am doing in my code that would lead to a non threadsafe condition.  I have read several threads on issues surrounding the StatefulKnowledgeSession so I have deliberately chosen to NOT share sessions between threads for that reason (and others).</span></p><p style="min-height: 8pt; height: 8pt; padding: 0px;"> </p><p><span style="font-size: 10pt; font-family: Arial, sans-serif;">A few main questions also:</span></p><p style="min-height: 8pt; height: 8pt; padding: 0px;"> </p><ul><li>Wrapping the Spring JTA PlatformTransactionManager in the DroolsSpringTransactionManager: i have seen this in several examples but have not seen any good explanation of whether/when it is necessary.</li><li>Use of the DroolsSpringJPAManager: again, have seen this in examples but no real documentation explaining it.</li><li>Should the StatefulKnowledgeSession be created inside a transaction?  Must it be the same transaction that it is used in?   I know that it has to be disposed outside of the transaction boundaries.</li></ul><p style="min-height: 8pt; height: 8pt; padding: 0px;"> </p><p><span style="font-size: 10pt; font-family: Arial, sans-serif;"><br/></span></p><p>Thanks for any help or suggestions.  I'm happy to provide more code as needed; I wanted to keep this limited to what seems relevant rather than zip up an entire complex application and force people to wade through all of it.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;"> </p><p>-- Jon Kranes</p><p style="min-height: 8pt; height: 8pt; padding: 0px;"> </p><p style="min-height: 8pt; height: 8pt; padding: 0px;"> </p><p style="min-height: 8pt; height: 8pt; padding: 0px;"> </p><p>Relevant code:</p><p style="min-height: 8pt; height: 8pt; padding: 0px;"> </p><p><span style="font-size: 10pt; font-family: Arial, sans-serif;">I have a wrapper class to hold a reference to the StatefulKnowledgeSession and its associated handlers, to make it easier to manage disposal:</span></p><p style="min-height: 8pt; height: 8pt; padding: 0px;"> </p><p><span style="font-size: 10pt; font-family: Arial, sans-serif;"><br/></span><pre class="jive-pre"><code class="jive-code jive-java"><font color="navy"><b>public</b></font> <font color="navy"><b>class</b></font> SessionWrapper <font color="navy">{</font>
 
<font color="navy"><b>private</b></font> <font color="navy"><b>static</b></font> Logger log = Logger.getLogger(SessionWrapper.class);
 
<font color="navy"><b>private</b></font> StatefulKnowledgeSession session;
<font color="navy"><b>private</b></font> GenericHTWorkItemHandler htHandler;
<font color="navy"><b>private</b></font> JPAWorkingMemoryDbLogger dbLogger;
<font color="navy"><b>private</b></font> LocalTaskService localTaskService;
 
<font color="navy"><b>public</b></font> <font color="navy"><b>void</b></font> dispose() <font color="navy">{</font>
<font color="navy"><b>try</b></font> <font color="navy">{</font>
                                                             log.info(<font color="red">"disposing local task service"</font>);
localTaskService.dispose();
<font color="navy">}</font>
<font color="navy"><b>catch</b></font> (Exception e) <font color="navy">{</font>
                                                             log.error(e);
<font color="navy">}</font>
<font color="navy"><b>try</b></font> <font color="navy">{</font>
                                                             <font color="darkgreen">// log.info("disposing db logger");</font>
                                                             <font color="darkgreen">// this does not do anything.</font>
<font color="darkgreen">// dbLogger.dispose();</font>
<font color="navy">}</font>
<font color="navy"><b>catch</b></font> (Exception e) <font color="navy">{</font>
                                                             log.error(e);
<font color="navy">}</font>
<font color="navy"><b>try</b></font> <font color="navy">{</font>
                                                             log.info(<font color="red">"disposing ht handler"</font>);
                                                             htHandler.dispose();
<font color="navy">}</font>
<font color="navy"><b>catch</b></font> (Exception e) <font color="navy">{</font>
                                                             log.error(e);
<font color="navy">}</font>
<font color="navy"><b>try</b></font> <font color="navy">{</font>
                                                             log.info(<font color="red">"Disposing session ID "</font> + session.getId());
                                                             session.dispose();
<font color="navy">}</font>
<font color="navy"><b>catch</b></font> (Exception e) <font color="navy">{</font>
log.error(e);
<font color="navy">}</font>
<font color="navy">}</font>
 
 
<font color="navy"><b>public</b></font> StatefulKnowledgeSession getSession() <font color="navy">{</font>
<font color="navy"><b>return</b></font> session;
<font color="navy">}</font>
<font color="navy"><b>public</b></font> <font color="navy"><b>void</b></font> setSession(StatefulKnowledgeSession session) <font color="navy">{</font>
this.session = session;
<font color="navy">}</font>
<font color="navy"><b>public</b></font> GenericHTWorkItemHandler getHtHandler() <font color="navy">{</font>
<font color="navy"><b>return</b></font> htHandler;
<font color="navy">}</font>
<font color="navy"><b>public</b></font> <font color="navy"><b>void</b></font> setHtHandler(GenericHTWorkItemHandler htHandler) <font color="navy">{</font>
this.htHandler = htHandler;
<font color="navy">}</font>
<font color="navy"><b>public</b></font> JPAWorkingMemoryDbLogger getDbLogger() <font color="navy">{</font>
<font color="navy"><b>return</b></font> dbLogger;
<font color="navy">}</font>
<font color="navy"><b>public</b></font> <font color="navy"><b>void</b></font> setDbLogger(JPAWorkingMemoryDbLogger dbLogger) <font color="navy">{</font>
this.dbLogger = dbLogger;
<font color="navy">}</font>
<font color="navy"><b>public</b></font> LocalTaskService getLocalTaskService() <font color="navy">{</font>
<font color="navy"><b>return</b></font> localTaskService;
<font color="navy">}</font>
<font color="navy"><b>public</b></font> <font color="navy"><b>void</b></font> setLocalTaskService(LocalTaskService localTaskService) <font color="navy">{</font>
this.localTaskService = localTaskService;
<font color="navy">}</font>
 
<font color="navy">}</font>
 
</code></pre></p><p style="min-height: 8pt; height: 8pt; padding: 0px;"> </p><p><span style="font-size: 10pt; font-family: Arial, sans-serif;">The SessionWrapper instance is created here</span></p><p style="min-height: 8pt; height: 8pt; padding: 0px;"> </p><p><span style="font-size: 10pt; font-family: Arial, sans-serif;"><br/></span><pre class="jive-pre"><code class="jive-code jive-java"><font color="navy"><b>public</b></font> <font color="navy"><b>class</b></font> KnowledgeSessionFactory <font color="navy">{</font>
 
@Autowired
KnowledgeBase kbase;
 
@Autowired
org.jbpm.task.service.TaskService taskService;
 
@Autowired
EntityManagerFactory emf;
 
@Autowired
EventDrivenTaskHandler handler;
 
@Autowired
         DroolsSpringTransactionManager txManager;
   
    @Autowired
    AuditService auditService;
   
    @Autowired
    AuditTaskHandler auditHandler;
  
    <font color="navy"><b>private</b></font> <font color="navy"><b>static</b></font> <font color="navy"><b>final</b></font> Logger log = Logger.getLogger(KnowledgeSessionFactory.class);
   
<font color="navy"><b>public</b></font> SessionWrapper createKnowledgeSession() <font color="navy">{</font>
log.info(<font color="red">"Creating new StatefulKnowledgeSession"</font>);
StatefulKnowledgeSession ksession = <font color="navy"><b>null</b></font>;
<font color="navy"><b>try</b></font> <font color="navy">{</font>
                                                             ksession = JPAKnowledgeService.newStatefulKnowledgeSession( kbase, null, getEnvironment() );
<font color="navy">}</font>
<font color="navy"><b>catch</b></font> (Exception e) <font color="navy">{</font>
                                                             log.error(<font color="red">"Unable to create sesssion!"</font>);
                                                             log.error(e);
                                                             <font color="navy"><b>throw</b></font> <font color="navy"><b>new</b></font> RuntimeException(e);
<font color="navy">}</font>
log.info(<font color="red">"Session ID: "</font> + ksession.getId());
<font color="navy"><b>return</b></font> createSessionWrapper(ksession);
<font color="navy">}</font>
 
<font color="navy"><b>public</b></font> SessionWrapper createKnowledgeSession(<font color="navy"><b>int</b></font> sessionId) <font color="navy">{</font>
log.info(<font color="red">"Loading StatefulKnowledgeSession for ID: "</font> + sessionId);
StatefulKnowledgeSession ksession = JPAKnowledgeService.loadStatefulKnowledgeSession(sessionId, kbase, null, getEnvironment());
<font color="navy"><b>return</b></font> createSessionWrapper(ksession);
<font color="navy">}</font>
 
<font color="navy"><b>private</b></font> SessionWrapper createSessionWrapper(StatefulKnowledgeSession ksession) <font color="navy">{</font>
LocalTaskService taskClient = <font color="navy"><b>new</b></font> LocalTaskService(taskService);
GenericHTWorkItemHandler htHandler = <font color="navy"><b>new</b></font> LocalHTWorkItemHandler(taskClient, ksession);
 
ksession.getWorkItemManager().registerWorkItemHandler(<font color="red">"Human Task"</font>, htHandler);
ksession.getWorkItemManager().registerWorkItemHandler(<font color="red">"Task"</font>, handler);
ksession.getWorkItemManager().registerWorkItemHandler(<font color="red">"Audit"</font>, auditHandler);
ksession.addEventListener(<font color="navy"><b>new</b></font> DroolsListener());
 
<font color="darkgreen">// This allows access of the global in script tasks</font>
ksession.setGlobal(<font color="red">"auditService"</font>, auditService);
 
JPAWorkingMemoryDbLogger dbLogger = <font color="navy"><b>new</b></font> JPAWorkingMemoryDbLogger(ksession);
SessionWrapper wrapper = <font color="navy"><b>new</b></font> SessionWrapper();
wrapper.setSession(ksession);
wrapper.setHtHandler(htHandler);
wrapper.setDbLogger(dbLogger);
wrapper.setLocalTaskService(taskClient);
<font color="navy"><b>return</b></font> wrapper;
               <font color="navy">}</font>
 
<font color="navy"><b>private</b></font> Environment getEnvironment() <font color="navy">{</font>
log.info(<font color="red">"creating environment"</font>);
env = KnowledgeBaseFactory.newEnvironment();
env.set(EnvironmentName.ENTITY_MANAGER_FACTORY, emf );
env.set(EnvironmentName.TRANSACTION_MANAGER, txManager);
PersistenceContextManager persistenceContextManager = <font color="navy"><b>new</b></font> DroolsSpringJpaManager(env);
env.set(EnvironmentName.PERSISTENCE_CONTEXT_MANAGER, persistenceContextManager);
log.info(<font color="red">"environment created"</font>);
<font color="navy"><b>return</b></font> env;
<font color="navy">}</font>
<font color="navy">}</font>
 
 
</code></pre></p><p><span style="font-size: 10pt; font-family: Arial, sans-serif;"><br/></span></p><p><span style="font-size: 10pt; font-family: Arial, sans-serif;">Here is the message driven bean that initiates starting new process instances:</span></p><p style="min-height: 8pt; height: 8pt; padding: 0px;"> </p><pre class="jive-pre"><code class="jive-code jive-java"><font color="navy"><b>public</b></font> <font color="navy"><b>class</b></font> StartProcessListener <font color="navy"><b>implements</b></font> MessageListener <font color="navy">{</font>
 
<font color="navy"><b>private</b></font> <font color="navy"><b>static</b></font> Logger log = Logger.getLogger(StartProcessListener.class);
 
@Autowired
EventService service;
 
@Autowired
KnowledgeSessionFactory factory;
 
@Autowired
SerializerMessageConverter converter;
 
<font color="navy"><b>public</b></font> <font color="navy"><b>void</b></font> onMessage(Message message) <font color="navy">{</font>
SessionWrapper wrapper = <font color="navy"><b>null</b></font>;
<font color="navy"><b>try</b></font> <font color="navy">{</font>
                                                             Map<String, Object> map = (Map<String, Object>)converter.fromMessage(message);
                                                             Map<String, Object> params = <font color="navy"><b>new</b></font> HashMap<String, Object>();
                                                             params.put(<font color="red">"returnStatus"</font>, <font color="red">"VALID"</font>);
                                                             params.put(<font color="red">"return"</font>, map.get(<font color="red">"return"</font>));
 
                                                             String processId = (String)map.get(<font color="red">"processId"</font>);
                                                             <font color="navy"><b>try</b></font> <font color="navy">{</font>
                                                                            wrapper = service.createSessionWrapper();
                                                                            service.startProcess(wrapper, processId, params);
                                                             <font color="navy">}</font>
                                                             <font color="navy"><b>catch</b></font> (Exception e) <font color="navy">{</font>
                                                                            log.error(e);
                                                             <font color="navy">}</font>
<font color="navy">}</font>
<font color="navy"><b>catch</b></font> (Exception e) <font color="navy">{</font>
                                                             log.error(e);
<font color="navy">}</font>
<font color="navy"><b>finally</b></font> <font color="navy">{</font>
                                                             <font color="navy"><b>if</b></font> (wrapper != <font color="navy"><b>null</b></font>) <font color="navy">{</font>
                                                                            wrapper.dispose();
                                                             <font color="navy">}</font>
<font color="navy">}</font>
<font color="navy">}</font>
 
</code></pre><p><span style="font-size: 10pt; font-family: Arial, sans-serif;"><br/></span></p><p>And finally the service class that uses declarative transactions:</p><p style="min-height: 8pt; height: 8pt; padding: 0px;"> </p><p style="min-height: 8pt; height: 8pt; padding: 0px;"> </p><pre class="jive-pre"><code class="jive-code jive-java"><font color="navy"><b>public</b></font> <font color="navy"><b>class</b></font> EventServiceImpl <font color="navy"><b>implements</b></font> EventService <font color="navy">{</font>
 
<font color="navy"><b>private</b></font> <font color="navy"><b>static</b></font> Logger log = Logger.getLogger(EventServiceImpl.class);
 
@Autowired
KnowledgeSessionFactory factory;
 
@Autowired
TaskService taskService;
 
@Override
@Transactional
<font color="navy"><b>public</b></font> SessionWrapper createSessionWrapper() <font color="navy">{</font>
<font color="navy"><b>return</b></font> factory.createKnowledgeSession();
<font color="navy">}</font>
 
@Transactional
@Override
<font color="navy"><b>public</b></font> <font color="navy"><b>void</b></font> startProcess(SessionWrapper wrapper, String processId, Map<String, Object> params) <font color="navy">{</font>
<font color="darkgreen">// SessionWrapper wrapper = factory.createKnowledgeSession();</font>
StatefulKnowledgeSession ksession = wrapper.getSession();
 
<font color="darkgreen">// initializes the human task handler for the session</font>
<font color="darkgreen">// org.jbpm.task.TaskService lts = LocalHumanTaskService.getTaskService(ksession);</font>
 
<font color="darkgreen">// this allows us to insert the processInstance into the session before starting it.</font>
ProcessInstance processInstance = ksession.createProcessInstance(processId, params);
<font color="darkgreen">// for drools</font>
ksession.insert(processInstance);
 
log.info(<font color="red">"Starting process instance"</font>);
ksession.startProcessInstance(processInstance.getId());
<font color="darkgreen">//return wrapper;</font>
<font color="navy">}</font>
 
@Transactional
@Override
               <font color="navy"><b>public</b></font> SessionWrapper completeWorkItem(<font color="navy"><b>int</b></font> sessionId, <font color="navy"><b>long</b></font> workItemId, Map<String, Object> results) <font color="navy">{</font>
SessionWrapper wrapper = factory.createKnowledgeSession(sessionId);
StatefulKnowledgeSession ksession = wrapper.getSession();
completeWorkItem(ksession, workItemId, results);
<font color="navy"><b>return</b></font> wrapper;
<font color="navy">}</font>
 
@Override
@Transactional
<font color="navy"><b>public</b></font> SessionWrapper completeTask(<font color="navy"><b>int</b></font> sessionId, Long taskId, Map<String, Object> results) <font color="navy">{</font>
log.info(<font color="red">"Completing task: "</font> + taskId);
 
<font color="navy"><b>for</b></font> (String key : results.keySet()) <font color="navy">{</font>
                                                             log.info(key + <font color="red">"="</font> + results.get(key));
<font color="navy">}</font>
 
<font color="darkgreen">// LocalTaskService lts = new LocalTaskService(taskService);</font>
<font color="darkgreen">// StatefulKnowledgeSession ksession = factory.getKnowledgeSession(sessionId);</font>
SessionWrapper wrapper = factory.createKnowledgeSession(sessionId);
StatefulKnowledgeSession ksession = wrapper.getSession();
 
<font color="darkgreen">// org.jbpm.task.TaskService lts = LocalHumanTaskService.getTaskService(ksession);</font>
org.jbpm.task.TaskService lts = wrapper.getLocalTaskService();
Task task = lts.getTask(taskId);
<font color="darkgreen">// int sessionId = task.getTaskData().getProcessSessionId();</font>
<font color="darkgreen">// completeWorkItem(sessionId, task.getTaskData().getWorkItemId(), results);</font>
 
<font color="navy"><b>try</b></font> <font color="navy">{</font>
                                                             lts.start(taskId, <font color="red">"USER"</font>);
<font color="navy">}</font>
<font color="navy"><b>catch</b></font> (Exception e) <font color="navy">{</font>
                                                             log.error(e);
<font color="navy">}</font>
 
<font color="navy"><b>try</b></font> <font color="navy">{</font>
                                                             ContentData contentData = ContentMarshallerHelper.marshal(results, <font color="navy"><b>null</b></font>);
                                                             lts.complete(taskId, <font color="red">"USER"</font>, contentData);
                                                             lts.disconnect(); <font color="darkgreen">// does this do anything useful?</font>
<font color="navy">}</font>
<font color="navy"><b>catch</b></font> (Exception e) <font color="navy">{</font>
                                                             log.error(e);
<font color="navy">}</font>
 
<font color="darkgreen">// for drools</font>
ProcessInstance pi = ksession.getProcessInstance(task.getTaskData().getProcessInstanceId());
ksession.insert(pi);
 
completeWorkItem(ksession, task.getTaskData().getWorkItemId(), results);
 
<font color="navy"><b>return</b></font> wrapper;
 
<font color="navy">}</font>
 
<font color="navy"><b>private</b></font> <font color="navy"><b>void</b></font> completeWorkItem(StatefulKnowledgeSession ksession, Long workItemId, Map<String, Object> results) <font color="navy">{</font>
log.info(<font color="red">"Completing work item: "</font> + workItemId);
ksession.getWorkItemManager().completeWorkItem(workItemId, results);
<font color="navy">}</font>
<font color="navy">}</font>
 
</code></pre><p><span style="font-size: 10pt; font-family: Arial, sans-serif;"><br/></span></p><p style="min-height: 8pt; height: 8pt; padding: 0px;"> </p><p>Spring configuration:</p><p style="min-height: 8pt; height: 8pt; padding: 0px;"> </p><p style="min-height: 8pt; height: 8pt; padding: 0px;"> </p><pre class="jive-pre"><code class="jive-code jive-xml"><span class="jive-xml-tag"><?xml version="1.0" encoding="UTF-8"?></span>
<span class="jive-xml-tag"><beans ... ></span>
                
    <span class="jive-xml-tag"><context:annotation-config /></span>
   
    <span class="jive-xml-comment"><!-- Loads all classes annotated with @Component or @Service -->
    <span class="jive-xml-tag"><context:component-scan base-package="org.mitre.irs.eda.bpm"/></span>
  
    <span class="jive-xml-tag"><context:property-placeholder location="classpath:eda.properties" order="2"/></span>    
   
          <span class="jive-xml-tag"><jee:jndi-lookup id="emf" jndi-name="persistence/emf"/></span>
 
          <!-- Spring JtaTransactionManager -->
          <span class="jive-xml-tag"><bean id="jtaTxManager" class="org.springframework.transaction.jta.JtaTransactionManager" /></span>
 
          <span class="jive-xml-tag"><bean id="txManager" class="org.drools.container.spring.beans.persistence.DroolsSpringTransactionManager"
                    c:ptm-ref="jtaTxManager" /></span>
          <span class="jive-xml-tag"><tx:annotation-driven transaction-manager="jtaTxManager" /></span>
 
          <span class="jive-xml-tag"><jpa:repositories base-package="org.mitre.irs.eda.common.repo" entity-manager-factory-ref="emf" transaction-manager-ref="jtaTxManager" /></span>
 
          <span class="jive-xml-tag"><bean id="jpaDialect" class="org.springframework.orm.jpa.vendor.HibernateJpaDialect" /></span> 
 
          <!-- JBPM -->
          <span class="jive-xml-tag"><bean id="sel" class="org.drools.SystemEventListenerFactory"
                    factory-method="getSystemEventListener" /></span>
          <span class="jive-xml-tag"><bean id="jbpmTaskService" class="org.jbpm.task.service.TaskService"
                    c:emf-ref="emf" c:systemEventListener-ref="sel" /></span>
         <span class="jive-xml-tag"><bean id="kbaseFactory" class="org.mitre.irs.eda.bpm.jbpm.KnowledgeBaseFactory" /></span>
   
         <span class="jive-xml-tag"><bean id="kbase" factory-bean="kbaseFactory" factory-method="newKnowledgeBase" /></span>
           
   
          <!-- Rabbit MQ --></span>
          <span class="jive-xml-tag"><rabbit:connection-factory id="connectionFactory" channel-cache-size="20"
                    username="${amqp.username}" password="${amqp.password}" host="${amqp.host}" port="${amqp.port}" /></span>
 
          <span class="jive-xml-tag"><rabbit:admin id="admin" connection-factory="connectionFactory" /></span>
          <span class="jive-xml-tag"><bean id="serializerConverter" class="org.springframework.amqp.support.converter.SerializerMessageConverter" /></span>
          <span class="jive-xml-tag"><rabbit:template id="amqpTemplate" connection-factory="connectionFactory" message-converter="serializerConverter"/></span>
          <span class="jive-xml-tag"><rabbit:queue id="start" name="process.start" /></span>
          <span class="jive-xml-tag"><rabbit:queue id="task.start" name="process.task.start" /></span>
          <span class="jive-xml-tag"><rabbit:queue id="task.complete" name="process.task.complete" /></span>
          <span class="jive-xml-tag"><bean id="startListener" class="org.mitre.irs.eda.bpm.listener.StartProcessListener" /></span>
          <span class="jive-xml-tag"><bean id="taskCompleteListener" class="org.mitre.irs.eda.bpm.listener.TaskCompleteListener" /></span>
          <span class="jive-xml-tag"><rabbit:listener-container connection-factory="connectionFactory" concurrency="4"></span>
                    <span class="jive-xml-tag"><rabbit:listener queues="start" ref="startListener" /></span>
                    <span class="jive-xml-tag"><rabbit:listener queues="task.complete" ref="taskCompleteListener" /></span>
          <span class="jive-xml-tag"></rabbit:listener-container></span>  
   
         
<span class="jive-xml-tag"></beans></span>
</code></pre></div>
<div style="background-color: #f4f4f4; padding: 10px; margin-top: 20px;">
<p style="margin: 0;">Reply to this message by <a href="https://community.jboss.org/message/828867#828867">going to Community</a></p>
        <p style="margin: 0;">Start a new discussion in jBPM at <a href="https://community.jboss.org/choose-container!input.jspa?contentType=1&containerType=14&container=2034">Community</a></p>
</div></td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</div>
</body>
</html>