1 2 Previous Next 17 Replies Latest reply on Apr 29, 2015 5:31 AM by Michael Awizen

    How to pass environment to CDI beans in Version 6.2.0.Final?

    Michael Awizen Novice

      Hi all,

      in the chapter 8.3.1. of jBPM user Guide there is a recommendation how to set the environment for an application executing in Container Managed Transaction (CMT) mode:

       

      Environment env = EnvironmentFactory.newEnvironment();
      env.set(EnvironmentName.ENTITY_MANAGER_FACTORY, emf);
      env.set(EnvironmentName.TRANSACTION_MANAGER, new ContainerManagedTransactionManager());
      env.set(EnvironmentName.PERSISTENCE_CONTEXT_MANAGER, new JpaProcessPersistenceContextManager(env));
      env.set(EnvironmentName.TASK_PERSISTENCE_CONTEXT_MANAGER, new JPATaskPersistenceContextManager(env));
      

       

       

      How do you suggest passing this environment in the CDI application?

       

      Currently I'm having trouble producing the RuntimeEnvironment described here ContainerManagedTransaction (CMT) configuration per CDI in jBPM 6.2 fails

        • 1. Re: How to pass environment to CDI beans in Version 6.2.0.Final?
          Maciej Swiderski Master

          take a look at this thread as it might be helpful. P.S. I believe the jira was still not filed...

           

          HTH

          • 2. Re: How to pass environment to CDI beans in Version 6.2.0.Final?
            Michael Awizen Novice

            Hi Maciej, thank you for the quick response. Yes, I read the thread. I'm afraid it provides no solution for the environment problem. I'm currently trying to build a workaround by implementing a modified HumanTaskServiceProducer ...

            • 3. Re: How to pass environment to CDI beans in Version 6.2.0.Final?
              Maciej Swiderski Master

              Michael,

               

              with the workaround given in that thread you don't need to configure environment any more to use CMT things as it will use the fake one and thus always assume it's in active transaction.

               

              HTH

              • 4. Re: How to pass environment to CDI beans in Version 6.2.0.Final?
                Michael Awizen Novice

                Ok, I tried the workaround from the thread. I have adopted the two classes ConfigureBean and FakeUserTransaction. I have placed the services directory in META-INF and the file "javax.enterprise.inject.spi.Extension" in it.

                 

                Sorry but the effect is quite like by jimmy001 directly after the application deployment on the WildFly 8.2:

                 

                19:14:53,880 WARN  [org.jboss.weld.Event] (MSC service thread 1-4) WELD-000411: Observer method [BackedAnnotatedMethod] org.jbpm.services.cdi.impl.ExcludeNonCDIImplExtension.processAnnotatedType(@Observes ProcessAnnotatedType<Object>, BeanManager) receives events for all annotated types. Consider restricting events using @WithAnnotations or a generic type with bounds.

                19:14:53,896 ERROR [stderr] (MSC service thread 1-4) java.lang.UnsupportedOperationException: JBAS011859: Naming context is read-only

                 

                19:14:53,896 ERROR [stderr] (MSC service thread 1-4)     at org.jboss.as.naming.WritableServiceBasedNamingStore.requireOwner(WritableServiceBasedNamingStore.java:161)

                 

                19:14:53,896 ERROR [stderr] (MSC service thread 1-4)     at org.jboss.as.naming.WritableServiceBasedNamingStore.bind(WritableServiceBasedNamingStore.java:66)

                 

                19:14:53,896 ERROR [stderr] (MSC service thread 1-4)     at org.jboss.as.naming.NamingContext.bind(NamingContext.java:253)

                 

                19:14:53,896 ERROR [stderr] (MSC service thread 1-4)     at org.jboss.as.naming.NamingContext.bind(NamingContext.java:262)

                 

                19:14:53,896 ERROR [stderr] (MSC service thread 1-4)     at com.awizen.gangehi.util.ConfigureBean.bindToJNDI(ConfigureBean.java:29)

                 

                19:14:53,896 ERROR [stderr] (MSC service thread 1-4)     at com.awizen.gangehi.util.ConfigureBean.beforeBeanDiscovery(ConfigureBean.java:16)

                 

                19:14:53,896 ERROR [stderr] (MSC service thread 1-4)     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

                 

                19:14:53,896 ERROR [stderr] (MSC service thread 1-4)     at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)

                 

                19:14:53,896 ERROR [stderr] (MSC service thread 1-4)     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

                 

                19:14:53,896 ERROR [stderr] (MSC service thread 1-4)     at java.lang.reflect.Method.invoke(Method.java:483)

                 

                19:14:53,896 ERROR [stderr] (MSC service thread 1-4)     at org.jboss.weld.injection.MethodInjectionPoint.invokeOnInstanceWithSpecialValue(MethodInjectionPoint.java:90)

                 

                19:14:53,896 ERROR [stderr] (MSC service thread 1-4)     at org.jboss.weld.event.ObserverMethodImpl.sendEvent(ObserverMethodImpl.java:271)

                 

                19:14:53,896 ERROR [stderr] (MSC service thread 1-4)     at org.jboss.weld.event.ExtensionObserverMethodImpl.sendEvent(ExtensionObserverMethodImpl.java:121)

                 

                19:14:53,896 ERROR [stderr] (MSC service thread 1-4)     at org.jboss.weld.event.ObserverMethodImpl.sendEvent(ObserverMethodImpl.java:258)

                 

                19:14:53,896 ERROR [stderr] (MSC service thread 1-4)     at org.jboss.weld.event.ObserverMethodImpl.notify(ObserverMethodImpl.java:237)

                 

                19:14:53,896 ERROR [stderr] (MSC service thread 1-4)     at org.jboss.weld.event.ObserverNotifier.notifyObserver(ObserverNotifier.java:174)

                 

                19:14:53,896 ERROR [stderr] (MSC service thread 1-4)     at org.jboss.weld.event.ObserverNotifier.notifyObservers(ObserverNotifier.java:133)

                 

                19:14:53,896 ERROR [stderr] (MSC service thread 1-4)     at org.jboss.weld.event.ObserverNotifier.fireEvent(ObserverNotifier.java:107)

                 

                19:14:53,896 ERROR [stderr] (MSC service thread 1-4)     at org.jboss.weld.bootstrap.events.AbstractContainerEvent.fire(AbstractContainerEvent.java:54)

                 

                19:14:53,896 ERROR [stderr] (MSC service thread 1-4)     at org.jboss.weld.bootstrap.events.AbstractDefinitionContainerEvent.fire(AbstractDefinitionContainerEvent.java:42)

                 

                19:14:53,896 ERROR [stderr] (MSC service thread 1-4)     at org.jboss.weld.bootstrap.events.BeforeBeanDiscoveryImpl.fire(BeforeBeanDiscoveryImpl.java:45)

                 

                19:14:53,896 ERROR [stderr] (MSC service thread 1-4)     at org.jboss.weld.bootstrap.WeldStartup.startInitialization(WeldStartup.java:360)

                 

                19:14:53,896 ERROR [stderr] (MSC service thread 1-4)     at org.jboss.weld.bootstrap.WeldBootstrap.startInitialization(WeldBootstrap.java:76)

                 

                19:14:53,896 ERROR [stderr] (MSC service thread 1-4)     at org.jboss.as.weld.WeldStartService.start(WeldStartService.java:91)

                 

                19:14:53,896 ERROR [stderr] (MSC service thread 1-4)     at org.jboss.msc.service.ServiceControllerImpl$StartTask.startService(ServiceControllerImpl.java:1948)

                 

                19:14:53,896 ERROR [stderr] (MSC service thread 1-4)     at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1881)

                 

                19:14:53,896 ERROR [stderr] (MSC service thread 1-4)     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)

                 

                19:14:53,896 ERROR [stderr] (MSC service thread 1-4)     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)

                 

                19:14:53,896 ERROR [stderr] (MSC service thread 1-4)     at java.lang.Thread.run(Thread.java:745)

                 

                 

                 

                Any suggestions?

                • 5. Re: How to pass environment to CDI beans in Version 6.2.0.Final?
                  Maciej Swiderski Master

                  is this war or ear deployment?

                   

                  I tested it with war deployment and it worked well, if you're running on ear then please attach ear reproducer so I can look into it.

                   

                  HTH

                  • 6. Re: How to pass environment to CDI beans in Version 6.2.0.Final?
                    Michael Awizen Novice

                    Pleas see the minimal ear application including the FakeUserTransaction workaround. It fails directly after the deployment on the WildFly 8.2 with java.lang.UnsupportedOperationException: JBAS011859: Naming context is read-only

                     

                    Thank you for your support!

                    • 7. Re: How to pass environment to CDI beans in Version 6.2.0.Final?
                      Michael Awizen Novice

                      By the way, even if the FakeUserTransaction workaround would work, don't you think this is a bit "dirty" solution?

                       

                      Is there a concept of passing of environment entries to jBPM CDI beans? Maybe some other way for the initialization of jBPM CDI services?

                      • 8. Re: How to pass environment to CDI beans in Version 6.2.0.Final?
                        Maciej Swiderski Master

                        Michael,

                         

                        thanks for the reproducer, I'll try to work on it as soon as I can and post it back here.

                         

                        Agreed, it's bit dirty solution as the name suggest it's workaround and not actual solution. So if you could file a jira for it as the problem is in JTATransactionManager in drools-persistence-jpa that is using always user transaction to check if transaction is active while it should use TransactionSynchronizationRegistry.

                         

                        It should be enough to add all environment entries in the producer that returns RuntimeEnvironment as that is required if you use CDI runtime manager. If you use jbpm services then the only way is to use deployment descriptor with resolvers (either mvel or reflection or create custom one)

                         

                        HTH

                        • 9. Re: How to pass environment to CDI beans in Version 6.2.0.Final?
                          Maciej Swiderski Master

                          Please find attached changed project. I removed all the fake UT code from the application and moved into jboss module so it can be registered in JNDI from application server point of view. Inside that zip you'll find module directory that includes all details and README.txt file with instruction on how to proceed.

                           

                          And again, this is just workaround until the JtaTransactionManager gets fixed.

                           

                          HTH

                          • 10. Re: How to pass environment to CDI beans in Version 6.2.0.Final?
                            Michael Awizen Novice

                            Thank you Maciej. Does this mean that ContainerManagedTransactionManager class is not necessary for CMT in the CDI scenario? I will check this fix tomorrow.

                             

                            For today just to proceed with my project I have chosen another workaround:

                             

                            I have placed a second TaskServiceFactory in my project. This second TaskServiceFactory is just a copy of your CDITaskServiceFactory:

                             

                            @ApplicationScoped
                            public class MyCDITaskServiceFactory implements TaskServiceFactory {
                            
                                @Inject
                                private Instance<TaskService> taskService;
                            
                                @Override
                                public TaskService newTaskService() {
                                    return taskService.get();
                                }
                            
                                @Override
                                public void close() {
                                }
                            }
                            
                            

                             

                            The presence of the second CDI bean of the same type causes a CDI exception. And in a case of exception the LocalTaskServiceFactory is chosen in your class RuntimeManagerFactoryCDIImpl. The constructor LocalTaskServiceFactory utilizes an instance of RuntimeEnvironment which contains the environment entries.

                             

                            With the following RuntimeEnvironment producer I could start my application then:

                             

                               @Produces
                               @Singleton
                               @PerRequest
                               @PerProcessInstance
                               public RuntimeEnvironment produceEnvironment(EntityManagerFactory emf) {
                            
                                  Environment env = EnvironmentFactory.newEnvironment();
                                  env.set(EnvironmentName.TRANSACTION_MANAGER, new ContainerManagedTransactionManager());
                                  env.set(EnvironmentName.ENTITY_MANAGER_FACTORY, emf);
                            
                                  JpaProcessPersistenceContextManager jpaProcessPersistenceContextManager = new JpaProcessPersistenceContextManager(env);
                                  JPATaskPersistenceContextManager jpaTaskPersistenceContextManager = new JPATaskPersistenceContextManager(env);
                            
                                  env.set(EnvironmentName.PERSISTENCE_CONTEXT_MANAGER, jpaProcessPersistenceContextManager);
                                  env.set(EnvironmentName.TASK_PERSISTENCE_CONTEXT_MANAGER, jpaTaskPersistenceContextManager);
                            
                            
                                  RuntimeEnvironment environment = RuntimeEnvironmentBuilder.Factory.get()
                                        .newDefaultBuilder()
                                        .addEnvironmentEntry(EnvironmentName.TRANSACTION_MANAGER, new ContainerManagedTransactionManager())
                                        .addEnvironmentEntry(EnvironmentName.TASK_PERSISTENCE_CONTEXT_MANAGER, jpaTaskPersistenceContextManager)
                                        .addEnvironmentEntry(EnvironmentName.PERSISTENCE_CONTEXT_MANAGER, jpaProcessPersistenceContextManager)
                                        .entityManagerFactory(emf)
                                        .registerableItemsFactory(factory)
                                        .addAsset(ResourceFactory.newClassPathResource("approval.bpmn"), ResourceType.BPMN2)
                                        .get();
                                  
                                  return environment;
                               }
                            
                            
                            • 11. Re: How to pass environment to CDI beans in Version 6.2.0.Final?
                              jimmy001 Apprentice

                              After installing the module I receive in my application:

                               

                              WARN  [org.jbpm.shared.services.impl.TransactionalCommandService] (

                              pool-16-thread-1) Could not commit session: javax.persistence.TransactionRequire

                              dException: No active JTA transaction on joinTransaction call

                                      at org.hibernate.jpa.spi.AbstractEntityManagerImpl.joinTransaction(Abstr

                              actEntityManagerImpl.java:1605) [hibernate-entitymanager-4.3.7.Final.jar:4.3.7.F

                              inal]

                                      at org.hibernate.jpa.spi.AbstractEntityManagerImpl.joinTransaction(Abstr

                              actEntityManagerImpl.java:1568) [hibernate-entitymanager-4.3.7.Final.jar:4.3.7.F

                              inal]

                                      at org.jbpm.shared.services.impl.JpaPersistenceContext.joinTransaction(J

                              paPersistenceContext.java:189) [jbpm-shared-services-6.2.0.CR4.jar:6.2.0.CR4]

                                      at org.jbpm.shared.services.impl.TransactionalCommandService.execute(Tra

                              nsactionalCommandService.java:41) [jbpm-shared-services-6.2.0.CR4.jar:6.2.0.CR4]

                               

                                      at org.jbpm.kie.services.impl.store.DeploymentStore.getDeploymentUnitsBy

                              Date(DeploymentStore.java:98) [jbpm-kie-services-6.2.0.CR4.jar:6.2.0.CR4]

                                      at org.jbpm.kie.services.impl.store.DeploymentSynchronizer.synchronize(D

                              eploymentSynchronizer.java:73) [jbpm-kie-services-6.2.0.CR4.jar:6.2.0.CR4]

                                      at org.jbpm.kie.services.impl.store.DeploymentSyncInvoker$TriggerDeploym

                              entSync.run(DeploymentSyncInvoker.java:81) [jbpm-kie-services-6.2.0.CR4.jar:6.2.

                              0.CR4]

                                      at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:47

                              1) [rt.jar:1.7.0_51]

                                      at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:304) [rt.

                              jar:1.7.0_51]

                                      at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.

                              access$301(ScheduledThreadPoolExecutor.java:178) [rt.jar:1.7.0_51]

                                      at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.

                              run(ScheduledThreadPoolExecutor.java:293) [rt.jar:1.7.0_51]

                                      at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.

                              java:1145) [rt.jar:1.7.0_51]

                                      at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor

                              .java:615) [rt.jar:1.7.0_51]

                                      at java.lang.Thread.run(Thread.java:744) [rt.jar:1.7.0_51]

                               

                              ERROR [org.jbpm.kie.services.impl.store.DeploymentSynchronizer] (po

                              ol-16-thread-1) Error while synchronizing deployments: No active JTA transaction

                              on joinTransaction call

                               

                               

                              So far it seems this error has no influence on my application. Meaning DeploymentService etc. seem to work.

                              • 12. Re: How to pass environment to CDI beans in Version 6.2.0.Final?
                                jimmy001 Apprentice

                                I found one thing, that puzzles me:

                                 

                                public ProcessInstance startProcessInstance(String deploymentId, String processDefinitionId,  HashMap<String, Object> details){
                                     long processId = processService.startProcess(deploymentId, processDefinitionId, details);
                                     LOG.debug("created processInstance with id => '{}', processId => '{}'", processId, processDefinitionId);
                                     ProcessInstance createdInstance = processService.getProcessInstance(processId);
                                     return createdInstance
                                }
                                
                                

                                 

                                After switching from BMT to CMT processService.getProcessInstance(processId) returns null.

                                But for tasks

                                 

                                public Task claim(long taskId, String userId){
                                     taskServiceJbpm.claim(taskId, userId);
                                     return getTask(taskId);
                                }
                                
                                public Task getTask(long taskId) {
                                     Task result = taskServiceJbpm.getTaskById(taskId);
                                     return result;
                                }
                                

                                 

                                works as I would expect it to and the lookup returns a task with status "claimed" (not "Ready" what I think would be the pendant to the above case).

                                Why is there a difference in the behaviour?

                                • 13. Re: How to pass environment to CDI beans in Version 6.2.0.Final?
                                  Michael Awizen Novice

                                  Ok, the module workaround works for me. There is no "NameNotFoundException: UserTransaction" any more when producing the RuntimeEnvironment.

                                  Thank you Maciej!

                                   

                                  I have voted for https://issues.jboss.org/browse/JBPM-4590 as this is the related issue.

                                  • 14. Re: How to pass environment to CDI beans in Version 6.2.0.Final?
                                    Michael Awizen Novice

                                    Sorry, I changed my mind: The "FakeUserTransaction" workaround does not work.

                                     

                                    The first problem with it is:

                                    Unresolved compilation problem:

                                        The method getStatus() of type FakeUserTransaction must override a superclass method

                                    reported by franco80 in https://developer.jboss.org/thread/252609?start=15&tstart=0

                                     

                                    After applying the fix introduced by jimmy001 in the same thread, the next problem arises:

                                    15:16:16,475 WARN  [org.hibernate.jpa.spi.AbstractEntityManagerImpl] (pool-8-thread-1) HHH000326: Cannot join transaction: do not override hibernate.transaction.factory_class

                                    15:16:16,475 WARN  [org.drools.persistence.SingleSessionCommandService] (pool-8-thread-1) Could not commit session: javax.persistence.TransactionRequiredException: No active JTA transaction on joinTransaction call

                                        at org.hibernate.jpa.spi.AbstractEntityManagerImpl.joinTransaction(AbstractEntityManagerImpl.java:1605) [hibernate-entitymanager-4.3.7.Final.jar:4.3.7.Final]

                                        at org.hibernate.jpa.spi.AbstractEntityManagerImpl.joinTransaction(AbstractEntityManagerImpl.java:1568) [hibernate-entitymanager-4.3.7.Final.jar:4.3.7.Final]

                                        at org.drools.persistence.jpa.JpaPersistenceContext.joinTransaction(JpaPersistenceContext.java:87) [drools-persistence-jpa.jar:6.2.0.Final]

                                        at org.drools.persistence.SingleSessionCommandService$TransactionInterceptor.execute(SingleSessionCommandService.java:519) [drools-persistence-jpa.jar:6.2.0.Final]

                                        at org.drools.core.command.impl.AbstractInterceptor.executeNext(AbstractInterceptor.java:41) [drools-core.jar:6.2.0.Final]

                                        at org.drools.persistence.jpa.OptimisticLockRetryInterceptor.execute(OptimisticLockRetryInterceptor.java:73) [drools-persistence-jpa.jar:6.2.0.Final]

                                        at org.drools.core.command.impl.AbstractInterceptor.executeNext(AbstractInterceptor.java:41) [drools-core.jar:6.2.0.Final]

                                        at org.drools.persistence.jta.TransactionLockInterceptor.execute(TransactionLockInterceptor.java:79) [drools-persistence-jpa.jar:6.2.0.Final]

                                        at org.drools.persistence.SingleSessionCommandService.execute(SingleSessionCommandService.java:358) [drools-persistence-jpa.jar:6.2.0.Final]

                                        at org.jbpm.process.core.timer.impl.GlobalTimerService$DisposableCommandService.execute(GlobalTimerService.java:299) [jbpm-flow.jar:6.2.0.Final]

                                        at org.jbpm.persistence.timer.GlobalJpaTimerJobInstance.call(GlobalJpaTimerJobInstance.java:77) [jbpm-persistence-jpa.jar:6.2.0.Final]

                                        at org.jbpm.persistence.timer.GlobalJpaTimerJobInstance.call(GlobalJpaTimerJobInstance.java:47) [jbpm-persistence-jpa.jar:6.2.0.Final]

                                        at java.util.concurrent.FutureTask.run(FutureTask.java:266) [rt.jar:1.8.0_25]

                                        at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180) [rt.jar:1.8.0_25]

                                        at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293) [rt.jar:1.8.0_25]

                                        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [rt.jar:1.8.0_25]

                                        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [rt.jar:1.8.0_25]

                                        at java.lang.Thread.run(Thread.java:745) [rt.jar:1.8.0_25]

                                    1 2 Previous Next