Bug 833609

Summary: JPAKnowledgeService sessions fail on CMT under other App Servers
Product: [JBoss] JBoss Enterprise BRMS Platform 5 Reporter: Babak Mozaffari <bmozaffa>
Component: BRE (Expert, Fusion)Assignee: Nobody <nobody>
Status: VERIFIED --- QA Contact:
Severity: medium Docs Contact:
Priority: unspecified    
Version: BRMS 5.3.0.GACC: kverlaen
Target Milestone: ER2   
Target Release: BRMS 5.3.1 GA   
Hardware: All   
OS: All   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Running JBoss Enterprise BRMS Business Process Management in a CMT environment caused a NullPointerExpection on WebSphere, because it did not allow access to UserTransaction, this made it impossible to run processes in the CMT environment. This has been resolved by implementing a dedicated TransactionManager to allow processes to run in the CMT environment.
Story Points: ---
Clone Of: Environment:
Last Closed: Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:

Description Babak Mozaffari 2012-06-19 21:10:19 UTC
Description of problem:
An attempt to use a JPA KnowledgeSession from a CMT context under non-JBoss application servers leads to an NPE.

Version-Release number of selected component (if applicable):
BRMS 5.3 ER9

How reproducible:
Create a simple EJB with default attributes and in a method, perform the following:
		KnowledgeBase kbase = agent.getKnowledgeBase();
		Environment env = KnowledgeBaseFactory.newEnvironment();
		env.set( EnvironmentName.ENTITY_MANAGER_FACTORY, emf );
		StatefulKnowledgeSession session = JPAKnowledgeService.newStatefulKnowledgeSession( kbase, null, env );
		ProcessInstance processInstance = session.startProcess( processId );



Steps to Reproduce:
1.
2.
3.
  
Actual results:
[6/18/12 17:22:53:268 PDT] 00000065 BusinessExcep E   CNTR0020E: EJB threw an unexpected (non-declared) exception during invocation of method "startProcess" on bean "BeanId(jBPM5 Embedded Application#jbpmService.jar#ProcessServiceBean, null)". Exception data: java.lang.IllegalStateException: java.lang.reflect.InvocationTargetException
	at org.drools.persistence.jpa.KnowledgeStoreServiceImpl.buildCommandService(KnowledgeStoreServiceImpl.java:143)
	at org.drools.persistence.jpa.KnowledgeStoreServiceImpl.newStatefulKnowledgeSession(KnowledgeStoreServiceImpl.java:67)
	at org.drools.persistence.jpa.JPAKnowledgeService.newStatefulKnowledgeSession(JPAKnowledgeService.java:122)
	at com.jboss.gbd.jbpm.embedded.ProcessServiceBean.startProcess(ProcessServiceBean.java:41)
...
...
...
Caused by: java.lang.NullPointerException
	at org.drools.persistence.jta.JtaTransactionManager.rollback(JtaTransactionManager.java:193)
	... 38 more


Expected results:


Additional info:
The culprit is https://github.com/droolsjbpm/drools/blob/master/drools-persistence-jpa/src/main/java/org/drools/persistence/jta/JtaTransactionManager.java

This class attempts a JNDI lookup of UserTransaction and then calls its getStatus() to find out if a container transaction might be active. In a CMT context, UserTransaction cannot be used, but JBoss allows it to be looked up and its status queried. Under WebSphere AS (8.5), the JNDI name for UserTransaction is simply not made available in CMT context and the findUserTransaction() method of JtaTransactionManager.java therefore fails with a NamingException and "ut" is set to null. This causes a subsequent NPE on getStatus()

P.S., the error handling in this class made it very difficult to troubleshoot. When the JNDI lookup fails, JtaTransactionManager is bound to fail sooner or later but the real cause of error is hidden with a debug level message and business is carried on until the inevitable NPE failure down the road. It would potentially be better to throw the original exception than to mask the error.

Comment 2 Maciej Swiderski 2012-09-11 17:38:16 UTC
Added dedicated TransactionManager (drools TM) implementation that fits CMT mode by assuming transaction is active and begin/rollback/commit is no-op. TransactionSynchronization is used as usual as WAS allows access to TransactionSynchronizationRegistry via JNDI lookup.

More information about it together with details on required configuration can be found in documentation section attached to this implementation (commit https://github.com/droolsjbpm/jbpm/commit/0ccc9a4f9e02f1fb2464344b5c395998f6cfda2d)

Most important is that since rollback is no-op, user implementation (inside business method of EJB, for example) must propagate all exceptions thrown by the engine up to container to properly rollback transaction managed by container.

Comment 3 Radovan Synek 2012-10-22 07:10:08 UTC
Verified on 5.3.1.BRMS-ER3