1 Reply Latest reply on Apr 24, 2015 4:38 AM by Francesco Scarcella

    ContainerManagedTransaction (CMT) configuration per CDI in jBPM 6.2 fails

    Michael Awizen Novice

      Hi all,

       

      I am integrating the jBPM RuntimeEnvironment into my Web-Application running on Wildfly 8.2. I use CDI for this. To enable the Container Managed Transaction (CMT)  I have added an environment entry TRANSACTION_MANAGER to the runtime environment (see line 12):

       

       

         @Produces
         @Singleton
         @PerRequest
         @PerProcessInstance
         public RuntimeEnvironment produceEnvironment(EntityManagerFactory emf) {
      
            RuntimeEnvironment environment = RuntimeEnvironmentBuilder.Factory.get()
                  .newDefaultBuilder()
                  .entityManagerFactory(emf)
                  .registerableItemsFactory(factory)
                  .addAsset(ResourceFactory.newClassPathResource("approval.bpmn"), ResourceType.BPMN2)
                  .addEnvironmentEntry(EnvironmentName.TRANSACTION_MANAGER, new ContainerManagedTransactionManager())
                  .get();
            return environment;
         }
      
      

       

      Now in the application the producing of RuntimeEnvironment ends up in the Exception:

          java.lang.IllegalStateException: Unable to find transaction: UserTransaction

       

      This happens because the environment is not utilized in the jBPM internal CommandBasedTaskService producer placed in HumanTaskServiceProducer (jbpm-services-cdi-6.2.0.Final.jar)  !

       

      Please see the producer method in public class HumanTaskServiceProducer:

       

         @Produces
         public CommandBasedTaskService produceTaskService() {
            if ( mode.equalsIgnoreCase( "none" ) ) {
               return null;
            }
            if ( taskService == null ) {
               HumanTaskConfigurator configurator = HumanTaskServiceFactory.newTaskServiceConfigurator()
                     .entityManagerFactory( emf )
                     .userGroupCallback( safeGet( userGroupCallback ) )
                     .userInfo( safeGet( userInfo ) );
      
               ...
         }
      

       

      Now compare the HumanTaskServiceProducer with LocalTaskServiceFactory from jbpm-runtime-manager-6.2.0.Final.jar

       

         @Override
         public TaskService newTaskService() {
            // all to reuse an already given instance of task service instead of producing new one
            TaskService providedTaskService = (TaskService) ((SimpleRuntimeEnvironment) runtimeEnvironment)
                  .getEnvironmentTemplate().get("org.kie.api.task.TaskService");
            if (providedTaskService != null) {
               return providedTaskService;
            }
            
            EntityManagerFactory emf = ((SimpleRuntimeEnvironment)runtimeEnvironment).getEmf();
            if (emf != null) {
               HumanTaskConfigurator configurator = HumanTaskServiceFactory.newTaskServiceConfigurator()
                     .environment(runtimeEnvironment.getEnvironment())
                     .entityManagerFactory(emf)               
                     .userGroupCallback(runtimeEnvironment.getUserGroupCallback());
               
               ...
         }
      

       

      In the line 13 of the listing the present environment is set to the HumanTaskConfigurator.

       

      I guess that omitting of the present environment in HumanTaskServiceProducer is a bug.

       

      Now my questions:

       

      Is there a way to produce the RuntimeEnvironment with the CMT configured?

      Is there a way maybe to suppress the production of incomplete CommandBasedTaskService when using CDI?

      Should I implement my own TaskService and my own producer for it? How?

      Any other suggestions regarding CMT and CDI in jBPM 6.2 ?