12 Replies Latest reply on Sep 23, 2010 5:00 AM by mwohlf

    Obtain a handle to ExecutionImpl from unit tests

    matrixpooh

      Hi,

       

      I need to be able to switch between in-memory and physical databases. In order to do so, I have two cfg files: jbpm.cfg.xml and jbpm.test.cfg.xml and depending on the database, use

       

      Configuration.getProcessEngine() 
      


      or

       

      new Configuration().setResource("jbpm.test.cfg.xml").buildProcessEngine()
      

       

      After that, I'd like to obtain the corresponding ProcessEngine from anywhere in my code including the unit tests. EnvironmentImpl.getFromCurrent(ProcessEngine.class) fails with something along the lines of "environment is not set".

       

      Any help will be greatly appreciated.

        • 1. Re: Obtain a handle to ExecutionImpl from unit tests
          rebody

          Hi Al,

            Why you need to get the processEngine from EnvironmentImpl?  Is there any reason that we have to get from processEngine?

          • 2. Re: Obtain a handle to ExecutionImpl from unit tests
            matrixpooh

            I'd like to execute commands via ProcessEngine.execute() and obtain handles to the services.

            • 3. Re: Obtain a handle to ExecutionImpl from unit tests
              rebody

              Hi Al,

               

                If you want to execute Command.  Please use env.get(CommandService.class).execute()

                if you want to get ***Service, Please use env.get(***Service.class)

               

                Anything else?

              1 of 1 people found this helpful
              • 4. Re: Obtain a handle to ExecutionImpl from unit tests
                matrixpooh

                I'm running in JVM, not in an application server or spring container. How do I obtain a handle to the environment?

                • 5. Re: Obtain a handle to ExecutionImpl from unit tests
                  mwohlf

                  Why don't you just extend JbpmTestCase, it should give you access to all you need

                  • 6. Re: Obtain a handle to ExecutionImpl from unit tests
                    matrixpooh

                    HuiSheng and Michael,

                     

                    Thanks for replies!

                     

                    For once, JbpmTestCase uses Configuration.buildProcessEngine() - i.e. it doesn't accomodate for different configuration files other than a default one.

                    I also need to be able to access services and commands from non-test classes. The reason being that my code base is broken into different modules and I'm trying to avoid a circular dependency between them by eliminating the need of passing jbpm services and commands around the modules. I'd rather instantiate pvm once and be able to obtain a handle to it anywhere in my codebase.

                     

                    HuiSheng's suggestion was close to what I'm looking for; unfortunately my pvm is running in JVM, not in anapplication server.

                    • 7. Re: Obtain a handle to ExecutionImpl from unit tests
                      mwohlf

                      alright Al,

                      I think what you want to do is this:

                       

                      import org.jbpm.api.Configuration;
                      import org.jbpm.api.ProcessEngine;
                      import org.jbpm.api.RepositoryService;
                      import org.jbpm.api.task.Task;
                      import org.jbpm.pvm.internal.cmd.CommandService;
                      import org.jbpm.pvm.internal.cmd.GetTaskCmd;
                      import org.jbpm.pvm.internal.env.EnvironmentImpl;
                      import org.jbpm.pvm.internal.processengine.ProcessEngineImpl;
                      
                      public class Start {
                      
                          private static volatile ProcessEngineImpl engine;
                      
                          public static void main(final String[] args) {
                              engine = (ProcessEngineImpl) new Configuration().setResource("jbpm4.jvm.cfg.xml").buildProcessEngine();
                              System.out.println("instanciated Engine in main: " + engine);
                              new Start().doSomeStuff();
                          }
                      
                          private void doSomeStuff() {
                              try {
                                  EnvironmentImpl environment = engine.openEnvironment();
                                  System.out.println("environment is: " + environment);
                      
                                  RepositoryService repositoryService = EnvironmentImpl.getFromCurrent(RepositoryService.class);
                                  System.out.println("repositoryService is : " + repositoryService);     
                                  long pdCount = repositoryService.createProcessDefinitionQuery().count();
                                  System.out.println("pdcount is: " + pdCount);
                      
                                  CommandService commandService = EnvironmentImpl.getFromCurrent(CommandService.class);
                                  System.out.println("commandService is : " + commandService);
                                  Task task = commandService.execute(new GetTaskCmd("4711"));
                                  System.out.println("task 4711 is : " + task);
                              } finally {
                                  engine.close();
                              }
                          }
                      
                      }
                      

                       

                      jbpm4.jvm.cfg.xml example file:

                       

                       

                      <?xml version="1.0" encoding="UTF-8"?>
                      
                      <jbpm-configuration>
                      
                        <process-engine-context>
                        
                          <task-service />
                          <repository-service />
                          <command-service />
                      
                          <command-service name="txRequiredCommandService">
                            <skip-interceptor />
                            <retry-interceptor />
                            <environment-interceptor />
                            <standard-transaction-interceptor />
                          </command-service>
                      
                          <command-service name="newTxRequiredCommandService">
                            <retry-interceptor />
                            <environment-interceptor policy="requiresNew" />
                            <standard-transaction-interceptor />
                          </command-service>
                      
                          <hibernate-configuration annotations="enabled">
                            <properties resource="jbpm4.jvm.hibernate.properties" />
                            <cfg resource="hibernate3.cfg.xml" />     
                          </hibernate-configuration>
                      
                          <hibernate-session-factory />
                          
                        </process-engine-context>
                      
                        <transaction-context>
                          <repository-session />
                          <transaction />
                          <hibernate-session />
                          <db-session />
                        </transaction-context>
                      
                      </jbpm-configuration>
                      
                      • 8. Re: Obtain a handle to ExecutionImpl from unit tests
                        matrixpooh

                        Michael,

                         

                        Thanks a bunch!

                         

                        My code almost worked as soon as I started doing

                         engine.openEnvironment();
                        

                          It passed quite a few steps but failed in an event listener when i tried to get CommandService.

                         

                        What finally made the trick was adding

                         <task-service />
                            <repository-service />
                            <command-service />

                        to cfg file.

                         

                        Again, thanks a bunch!

                        • 9. Re: Obtain a handle to ExecutionImpl from unit tests
                          matrixpooh

                          Need a little more of your help

                           

                          Seems like I'm almost there, but not quite.

                           

                          My test class below successfully passes first test and fails on the second

                           

                          package workflow;
                          
                          import java.io.BufferedReader;
                          import java.io.InputStreamReader;
                          import java.util.Iterator;
                          import java.util.Set;
                          
                          import org.apache.log4j.Logger;
                          import org.jbpm.api.Configuration;
                          import org.jbpm.api.IdentityService;
                          import org.jbpm.api.ProcessEngine;
                          import org.jbpm.pvm.internal.env.EnvironmentImpl;
                          import org.jbpm.pvm.internal.processengine.ProcessEngineImpl;
                          import org.junit.After;
                          import org.junit.Before;
                          import org.junit.Ignore;
                          import org.junit.Test;
                          
                          import com.gs.crd.requestmanager.identity.service.IdentityManager;
                          import com.gs.crd.requestmanager.workflow.identity.JbpmIdentityManager;
                          
                          public class IdentityTest {
                          
                              private static final Logger log = Logger.getLogger(IdentityTest.class);
                          
                              ProcessEngine pe;
                              
                              @Before
                              public  void initialize() throws Exception {
                              
                                  pe = new Configuration().setResource("jbpm.test.cfg.xml").buildProcessEngine();
                                  ((ProcessEngineImpl)pe).openEnvironment();
                              }
                          
                              
                              @After
                              public void tearDown(){
                                  pe.close();
                              }
                              
                          
                              @Test
                              public void testCreateUsersFromFile() throws Exception{
                                  IdentityService identityService = EnvironmentImpl.getFromCurrent(IdentityService.class);
                                  
                                  BufferedReader in = new BufferedReader(new InputStreamReader(
                                          getClass().getClassLoader().getResourceAsStream("DemoForUatUsers.txt")));
                                  
                                  String lineInInputFile = null;
                          
                                  int countCreated = 0;
                                  int countSkipped = 0;
                                  while ((lineInInputFile = in.readLine()) != null) {
                                      String user[] = lineInInputFile.split("\\|");
                          
                                      String userName = user[0].trim();
                                      String firstName = user[1].trim();
                                      String lastName = user[2].trim();
                          
                                      if(identityService.findUserById(userName) != null){
                                          countSkipped++;
                                          continue;
                                      }
                                      identityService.createUser(userName, firstName, lastName);            
                                      countCreated++;
                                      log.info("****************** Created user("+ userName +") ******************");
                                      Thread.sleep(100);
                                  }
                                  log.info(" Created " + countCreated + " users, Skipped " +countSkipped+" users");
                              }
                          
                              @Test
                              public void testCreateGroupsFromFile() throws Exception{
                                  IdentityService identityService = EnvironmentImpl.getFromCurrent(IdentityService.class);
                                  
                                  BufferedReader in = new BufferedReader(new InputStreamReader(
                                          getClass().getClassLoader().getResourceAsStream("Groups.txt")));
                                  
                                  String lineInInputFile = null;
                          
                                  while ((lineInInputFile = in.readLine()) != null) {
                                      String groupName = lineInInputFile.trim();
                          
                                      if(identityService.findGroupById(groupName) != null){
                                          continue;
                                      }
                                      
                                      identityService.createGroup(groupName);            
                                      log.info("****************** Created group("+ groupName +") ******************");
                                      Thread.sleep(100);
                                  }
                              }
                          }
                          

                           

                          The exception is:

                           

                          org.jbpm.api.JbpmException: couldn't acquire block of ids
                              at org.jbpm.pvm.internal.id.DatabaseDbidGenerator.getNextId(DatabaseDbidGenerator.java:65)
                              at org.jbpm.pvm.internal.identity.impl.IdentitySessionImpl.createUser(IdentitySessionImpl.java:60)
                              at org.jbpm.pvm.internal.identity.cmd.CreateUserCmd.execute(CreateUserCmd.java:57)
                              at org.jbpm.pvm.internal.identity.cmd.CreateUserCmd.execute(CreateUserCmd.java:32)
                              at org.jbpm.pvm.internal.svc.DefaultCommandService.execute(DefaultCommandService.java:42)
                              at org.jbpm.pvm.internal.svc.SkipInterceptor.execute(SkipInterceptor.java:40)
                              at org.jbpm.pvm.internal.svc.IdentityServiceImpl.createUser(IdentityServiceImpl.java:50)
                              at com.gs.crd.requestmanager.workflow.identity.IdentitySetup.createUsers(IdentitySetup.java:9)
                              at com.gs.crd.requestmanager.service.workflow.command.InitWorkflowServiceForTestsCommand.loadRefData(InitWorkflowServiceForTestsCommand.java:46)
                              at com.gs.crd.requestmanager.service.workflow.command.InitWorkflowServiceForTestsCommand.construct(InitWorkflowServiceForTestsCommand.java:29)
                              at com.gs.crd.requestmanager.service.workflow.command.InitWorkflowServiceForTestsCommand.construct(InitWorkflowServiceForTestsCommand.java:1)
                              at com.gs.crd.requestmanager.service.identity.IdentityTest.initialize(IdentityTest.java:42)
                              at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
                              at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
                              at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
                              at java.lang.reflect.Method.invoke(Method.java:597)
                              at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
                              at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
                              at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
                              at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:27)
                              at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
                              at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:76)
                              at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
                              at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
                              at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
                              at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
                              at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
                              at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
                              at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
                              at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:49)
                              at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
                              at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
                              at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
                              at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
                              at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
                          Caused by: java.lang.NullPointerException
                              at org.jbpm.pvm.internal.id.AcquireDbidBlockCmd.execute(AcquireDbidBlockCmd.java:29)
                              at org.jbpm.pvm.internal.id.AcquireDbidBlockCmd.execute(AcquireDbidBlockCmd.java:12)
                              at org.jbpm.pvm.internal.svc.DefaultCommandService.execute(DefaultCommandService.java:42)
                              at org.jbpm.pvm.internal.tx.StandardTransactionInterceptor.execute(StandardTransactionInterceptor.java:50)
                              at org.jbpm.pvm.internal.svc.EnvironmentInterceptor.executeInNewEnvironment(EnvironmentInterceptor.java:53)
                              at org.jbpm.pvm.internal.svc.EnvironmentInterceptor.execute(EnvironmentInterceptor.java:40)
                              at org.jbpm.pvm.internal.svc.RetryInterceptor.execute(RetryInterceptor.java:56)
                              at org.jbpm.pvm.internal.id.DatabaseDbidGenerator.acquireDbidBlock(DatabaseDbidGenerator.java:76)
                              at org.jbpm.pvm.internal.id.DatabaseDbidGenerator.getNextId(DatabaseDbidGenerator.java:63)
                              ... 34 more

                           

                           

                           

                          Here's my jbpm.test.cfg.xml:

                           

                          Al Nadein wrote:

                          <?xml version="1.0" encoding="UTF-8"?>

                          <jbpm-configuration>

                              <import resource="jbpm.default.cfg.xml" />
                              <import resource="jbpm.jpdl.cfg.xml" />
                              <import resource="jbpm.identity.cfg.xml" />


                              <process-engine-context>

                                  <task-service />
                                  <repository-service />
                                  <command-service />

                                  <command-service name="txRequiredCommandService">
                                      <skip-interceptor />
                                      <retry-interceptor />
                                      <environment-interceptor />
                                      <standard-transaction-interceptor />
                                  </command-service>

                                  <command-service name="newTxRequiredCommandService">
                                      <retry-interceptor />
                                      <environment-interceptor policy="requiresNew" />
                                      <standard-transaction-interceptor />
                                  </command-service>

                                  <hibernate-configuration annotations="enabled">
                                      <cfg resource="jbpm.hibernate.test.cfg.xml" />
                                  </hibernate-configuration>

                                  <hibernate-session-factory />

                              </process-engine-context>

                              <transaction-context>
                                  <transaction />
                                  <hibernate-session />
                              </transaction-context>

                          </jbpm-configuration>
                          • 10. Re: Obtain a handle to ExecutionImpl from unit tests
                            mwohlf

                            you might need something like

                             

                                <object class="org.jbpm.pvm.internal.id.DatabaseDbidGenerator">
                                  <field name="commandService"><ref object="newTxRequiredCommandService" /></field>
                                </object>
                            
                                <object class="org.jbpm.pvm.internal.id.DatabaseIdComposer" init="eager" />
                            

                             

                            in your config

                            • 11. Re: Obtain a handle to ExecutionImpl from unit tests
                              matrixpooh

                              Thanks for giving a hand, Michael!

                               

                              Went through the previous posts and saw that suggestion. Checked to ensure I have <object/> tag. Still no luck.

                              • 12. Re: Obtain a handle to ExecutionImpl from unit tests
                                mwohlf

                                as far as I can tell from the stacktrace the property for the next entity id can't be found in the database.

                                Usually this property should be set at engine creation time with the CheckDbCmd(). You should be able to manually set it with

                                commandService.execute(new CheckDbCmd());