6 Replies Latest reply on Nov 27, 2014 1:32 AM by Maciej Swiderski

    random error when I launch the process

    Domenico Schiavone Newbie

      I have a process with the sequence "servicetask-humantask-servicetask".

      I have used thread in the executeWorkItem.

      when I launch 2 times the same process I lost a final service task, and sometimes the console return me any errors.

      If i launch 2 different process with the same task I lost nothing, but the error appear yet.

       

      the code of the main process is:

      public class ProcessMain {

          KieServices ks;

          KieContainer kContainer;

          KieBase kbase;

       

          RuntimeManager manager;

          RuntimeEngine engine;

          KieSession ksession;

          TaskService taskService;

          AuditService logService;

         

          Map<String, Object> paramsHello = new HashMap<String, Object>();

          Map<String, Object> params = new HashMap<String, Object>();

       

         

          public ProcessMain(){

              this.ks = KieServices.Factory.get();

              this.kContainer = ks.getKieClasspathContainer();

              this.kbase = kContainer.getKieBase("kbase");

       

              this.manager = createRuntimeManager(kbase);

              this.engine = manager.getRuntimeEngine(null);

              this.ksession = engine.getKieSession();

              this.taskService = engine.getTaskService();

              this.logService = engine.getAuditLogService();

             

              ksession.getWorkItemManager().registerWorkItemHandler("Smile",(WorkItemHandler) new Smile(ksession));

             

              paramsHello.put("variable1", "Saluti a tutti hello");

             

              params.put("variable1", "Saluti a tutti");

             

          }

       

          public void start() {

             

       

              ksession.startProcess("com.sample.bpmn.hello", paramsHello);

              ksession.startProcess("com.sample.bpmn.hello", paramsHello);

       

              // let john execute Task 1

              List<TaskSummary> list = taskService.getTasksAssignedAsPotentialOwner("john", "en-UK");

              TaskSummary task = list.get(0);

              System.out.println("John is executing task " + task.getName());

              taskService.start(task.getId(), "john");

              taskService.complete(task.getId(), "john", null);

       

              // let mary execute Task 2

              list = taskService.getTasksAssignedAsPotentialOwner("mary", "en-UK");

              task = list.get(0);

              System.out.println("Mary is executing task " + task.getName());

              taskService.start(task.getId(), "mary");

              taskService.complete(task.getId(), "mary", null);

             

             

              manager.disposeRuntimeEngine(engine);

              System.exit(0);

          }

       

          private static RuntimeManager createRuntimeManager(KieBase kbase) {

              JBPMHelper.startH2Server();

              JBPMHelper.setupDataSource();

              EntityManagerFactory emf = Persistence.createEntityManagerFactory("org.jbpm.persistence.jpa");

              RuntimeEnvironmentBuilder builder = RuntimeEnvironmentBuilder.Factory.get()

                  .newDefaultBuilder().entityManagerFactory(emf)

                  .knowledgeBase(kbase);

              return RuntimeManagerFactory.Factory.get()

                  .newSingletonRuntimeManager(builder.get(), "com.sample:example:1.0");

          }

       

      }

       


      The code of workItem is:

      public class Smile implements WorkItemHandler{

          private KieSession ksession;

         

          public Smile(KieSession ksession) {

              this.ksession = ksession;

              }

       

           public void abortWorkItem(WorkItem workItem, WorkItemManager manager) {

                  manager.abortWorkItem(workItem.getId());

                }

       

          public void executeWorkItem(WorkItem workItem, WorkItemManager manager) {

              final Object p= workItem.getParameter("param1");

             

              final String deploymentId = nonNull(((WorkItemImpl)workItem).getDeploymentId());

              final long processInstanceId = workItem.getProcessInstanceId();

              final long workItemId = workItem.getId();

             

              new Thread(new Runnable() {

       

       

                    public void run() {

                           System.out.println(p);

                           System.out.println(deploymentId +"|"+ processInstanceId +"|"+ workItemId);

                           RuntimeManager manager = RuntimeManagerRegistry.get().getManager(deploymentId);

                           if (manager != null) {

                           RuntimeEngine engine = manager.getRuntimeEngine(ProcessInstanceIdContext.get(processInstanceId));

                           engine.getKieSession().getWorkItemManager().completeWorkItem(workItemId, null);

                           manager.disposeRuntimeEngine(engine);

                           } else {

                           // in case there is no RuntimeManager available use available ksession,

                           // as it might be used without runtime manager at all

                           ksession.getWorkItemManager().completeWorkItem(workItemId, null);

                           }

                          

                    }

                  }).start();

       

            }

         

          protected String nonNull(String value) {

              if (value == null) {

              return "";

              }

              return value;

              }  

         

      }

       

      Where am I wrong??

        • 1. Re: random error when I launch the process
          Domenico Schiavone Newbie

          the error that give me the console is:

          Exception in thread "Thread-7" javax.persistence.PersistenceException: org.hibernate.exception.GenericJDBCException: could not prepare statement

              at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1387)

              at org.hibernate.ejb.AbstractEntityManagerImpl.find(AbstractEntityManagerImpl.java:838)

              at org.hibernate.ejb.AbstractEntityManagerImpl.find(AbstractEntityManagerImpl.java:781)

              at org.drools.persistence.jpa.JpaPersistenceContext.findWorkItemInfo(JpaPersistenceContext.java:86)

              at org.drools.persistence.jpa.processinstance.JPAWorkItemManager.completeWorkItem(JPAWorkItemManager.java:121)

              at org.drools.core.command.runtime.process.CompleteWorkItemCommand.execute(CompleteWorkItemCommand.java:74)

              at org.drools.core.command.runtime.process.CompleteWorkItemCommand.execute(CompleteWorkItemCommand.java:35)

              at org.drools.core.command.impl.DefaultCommandService.execute(DefaultCommandService.java:36)

              at org.drools.core.command.impl.AbstractInterceptor.executeNext(AbstractInterceptor.java:41)

              at org.drools.persistence.SingleSessionCommandService$TransactionInterceptor.execute(SingleSessionCommandService.java:509)

              at org.drools.core.command.impl.AbstractInterceptor.executeNext(AbstractInterceptor.java:41)

              at org.drools.persistence.jpa.OptimisticLockRetryInterceptor.execute(OptimisticLockRetryInterceptor.java:73)

              at org.drools.core.command.impl.AbstractInterceptor.executeNext(AbstractInterceptor.java:41)

              at org.drools.persistence.jta.TransactionLockInterceptor.execute(TransactionLockInterceptor.java:60)

              at org.drools.persistence.SingleSessionCommandService.execute(SingleSessionCommandService.java:353)

              at org.drools.core.command.impl.CommandBasedStatefulKnowledgeSession$1.completeWorkItem(CommandBasedStatefulKnowledgeSession.java:145)

              at com.sample.Smile$1.run(Smile.java:52)

              at java.lang.Thread.run(Thread.java:745)

          Caused by: org.hibernate.exception.GenericJDBCException: could not prepare statement

              at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:54)

              at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:124)

              at org.hibernate.engine.jdbc.internal.StatementPreparerImpl$StatementPreparationTemplate.prepareStatement(StatementPreparerImpl.java:193)

              at org.hibernate.engine.jdbc.internal.StatementPreparerImpl.prepareQueryStatement(StatementPreparerImpl.java:157)

              at org.hibernate.loader.Loader.prepareQueryStatement(Loader.java:1881)

              at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1858)

              at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1838)

              at org.hibernate.loader.Loader.doQuery(Loader.java:906)

              at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:348)

              at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:318)

              at org.hibernate.loader.Loader.loadEntity(Loader.java:2145)

              at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:82)

              at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:72)

              at org.hibernate.persister.entity.AbstractEntityPersister.load(AbstractEntityPersister.java:3939)

              at org.hibernate.event.internal.DefaultLoadEventListener.loadFromDatasource(DefaultLoadEventListener.java:462)

              at org.hibernate.event.internal.DefaultLoadEventListener.doLoad(DefaultLoadEventListener.java:431)

              at org.hibernate.event.internal.DefaultLoadEventListener.load(DefaultLoadEventListener.java:208)

              at org.hibernate.event.internal.DefaultLoadEventListener.proxyOrLoad(DefaultLoadEventListener.java:264)

              at org.hibernate.event.internal.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:152)

              at org.hibernate.internal.SessionImpl.fireLoad(SessionImpl.java:1017)

              at org.hibernate.internal.SessionImpl.access$2000(SessionImpl.java:173)

              at org.hibernate.internal.SessionImpl$IdentifierLoadAccessImpl.load(SessionImpl.java:2413)

              at org.hibernate.internal.SessionImpl.get(SessionImpl.java:913)

              at org.hibernate.ejb.AbstractEntityManagerImpl.find(AbstractEntityManagerImpl.java:807)

              ... 16 more

          Caused by: org.h2.jdbc.JdbcSQLException: Connection is broken: "session closed" [90067-168]

              at org.h2.message.DbException.getJdbcSQLException(DbException.java:329)

              at org.h2.message.DbException.get(DbException.java:169)

              at org.h2.message.DbException.get(DbException.java:146)

              at org.h2.engine.SessionRemote.checkClosed(SessionRemote.java:502)

              at org.h2.engine.SessionRemote.removeServer(SessionRemote.java:433)

              at org.h2.command.CommandRemote.prepare(CommandRemote.java:80)

              at org.h2.command.CommandRemote.<init>(CommandRemote.java:46)

              at org.h2.engine.SessionRemote.prepareCommand(SessionRemote.java:439)

              at org.h2.jdbc.JdbcConnection.prepareCommand(JdbcConnection.java:1109)

              at org.h2.jdbc.JdbcPreparedStatement.<init>(JdbcPreparedStatement.java:74)

              at org.h2.jdbc.JdbcConnection.prepareStatement(JdbcConnection.java:264)

              at sun.reflect.GeneratedMethodAccessor32.invoke(Unknown Source)

              at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

              at java.lang.reflect.Method.invoke(Method.java:606)

              at bitronix.tm.resource.jdbc.BaseProxyHandlerClass.invoke(BaseProxyHandlerClass.java:64)

              at com.sun.proxy.$Proxy5.prepareStatement(Unknown Source)

              at bitronix.tm.resource.jdbc.JdbcConnectionHandle.prepareStatement(JdbcConnectionHandle.java:257)

              at sun.reflect.GeneratedMethodAccessor31.invoke(Unknown Source)

              at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

              at java.lang.reflect.Method.invoke(Method.java:606)

              at bitronix.tm.resource.jdbc.BaseProxyHandlerClass.invoke(BaseProxyHandlerClass.java:64)

              at com.sun.proxy.$Proxy5.prepareStatement(Unknown Source)

              at org.hibernate.engine.jdbc.internal.StatementPreparerImpl$5.doPrepare(StatementPreparerImpl.java:159)

              at org.hibernate.engine.jdbc.internal.StatementPreparerImpl$StatementPreparationTemplate.prepareStatement(StatementPreparerImpl.java:183)

              ... 37 more

          • 2. Re: random error when I launch the process
            Maciej Swiderski Master

            since you use singleton runtime manager strategy it might be that two transactions to run into race condition. Try enabling transaction lock interceptor by setting system property:

            -Dorg.kie.tx.lock.enabled=true

            that might help in intermittent problems with "stealing" resources by different threads.

             

            HTH

            • 3. Re: random error when I launch the process
              Domenico Schiavone Newbie

              how do i change the system property??

              • 4. Re: random error when I launch the process
                Maciej Swiderski Master

                depending how you start your program it could be as easy as adding -Dorg.kie.tx.lock.enabled=true to the command line e.g. when you start JBoss server: ./standalone.sh -Dorg.kie.tx.lock.enabled=true

                 

                or you can do it programmatically:

                System.setProperty("org.kie.tx.lock.enabled", "true");

                 

                and this shall be first line in your program.

                 

                HTH

                • 5. Re: random error when I launch the process
                  Domenico Schiavone Newbie

                  I start the program through Eclipse launching the main class. I don't use jBOSS server.

                  Then I don't know how to use this command: "System.setProperty("org.kie.tx.lock.enabled", "true");" in my main class view before

                  • 6. Re: random error when I launch the process
                    Maciej Swiderski Master

                    just put it into your program as first line of the method that call jBPM api.

                     

                    HTH