Can timeCycle be made dynamic<startEvent id="startEvent"> <timerEventDefinition> <timeCycle>${expression}</timeCycle> </timerEventDefinition> </startEvent>

However getting error-
Exception in thread “main” org.flowable.engine.common.api.FlowableException: Unknown property used in expression: ${expression}
at org.flowable.engine.impl.el.JuelExpression.getValue(JuelExpression.java:60)
at org.flowable.engine.impl.util.TimerUtil.createTimerEntityForTimerEventDefinition(TimerUtil.java:98)
at org.flowable.engine.impl.asyncexecutor.DefaultJobManager.createTimerJob(DefaultJobManager.java:108)
at org.flowable.engine.impl.bpmn.deployer.TimerManager.getTimerDeclarations(TimerManager.java:75)
at org.flowable.engine.impl.bpmn.deployer.TimerManager.scheduleTimers(TimerManager.java:58)
at org.flowable.engine.impl.bpmn.deployer.BpmnDeploymentHelper.updateTimersAndEvents(BpmnDeploymentHelper.java:153)
at org.flowable.engine.impl.bpmn.deployer.BpmnDeployer.updateTimersAndEvents(BpmnDeployer.java:212)
at org.flowable.engine.impl.bpmn.deployer.BpmnDeployer.deploy(BpmnDeployer.java:87)
at org.flowable.engine.impl.persistence.deploy.DeploymentManager.deploy(DeploymentManager.java:60)
at org.flowable.engine.impl.cmd.DeployCmd.executeDeploy(DeployCmd.java:116)
at org.flowable.engine.impl.cmd.DeployCmd.execute(DeployCmd.java:66)
at org.flowable.engine.impl.cmd.DeployCmd.execute(DeployCmd.java:40)
at org.flowable.engine.impl.interceptor.CommandInvoker$1.run(CommandInvoker.java:44)
at org.flowable.engine.impl.interceptor.CommandInvoker.executeOperation(CommandInvoker.java:86)
at org.flowable.engine.impl.interceptor.CommandInvoker.executeOperations(CommandInvoker.java:65)
at org.flowable.engine.impl.interceptor.CommandInvoker.execute(CommandInvoker.java:49)
at org.flowable.engine.impl.interceptor.TransactionContextInterceptor.execute(TransactionContextInterceptor.java:51)
at org.flowable.engine.impl.interceptor.CommandContextInterceptor.execute(CommandContextInterceptor.java:64)
at org.flowable.engine.impl.interceptor.LogInterceptor.execute(LogInterceptor.java:36)
at org.flowable.engine.impl.cfg.CommandExecutorImpl.execute(CommandExecutorImpl.java:56)
at org.flowable.engine.impl.cfg.CommandExecutorImpl.execute(CommandExecutorImpl.java:51)
at org.flowable.engine.impl.RepositoryServiceImpl.deploy(RepositoryServiceImpl.java:93)
at org.flowable.engine.impl.repository.DeploymentBuilderImpl.deploy(DeploymentBuilderImpl.java:188)
at SchedulingTest.SchedulingClassTest.main(SchedulingClassTest.java:28)
Caused by: javax.el.PropertyNotFoundException: Cannot resolve identifier 'expression’
at de.odysseus.el.tree.impl.ast.AstIdentifier.eval(AstIdentifier.java:93)
at de.odysseus.el.tree.impl.ast.AstEval.eval(AstEval.java:51)
at de.odysseus.el.tree.impl.ast.AstNode.getValue(AstNode.java:31)
at de.odysseus.el.TreeValueExpression.getValue(TreeValueExpression.java:122)
at org.flowable.engine.impl.delegate.invocation.ExpressionGetInvocation.invoke(ExpressionGetInvocation.java:33)
at org.flowable.engine.impl.delegate.invocation.DelegateInvocation.proceed(DelegateInvocation.java:35)
at org.flowable.engine.impl.delegate.invocation.DefaultDelegateInterceptor.handleInvocation(DefaultDelegateInterceptor.java:25)
at org.flowable.engine.impl.el.JuelExpression.getValue(JuelExpression.java:56)
… 23 more

Can you paste the snipper of your bpmn 2.0 xml?

Have you properly set the expression variable?

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

<startEvent id="startEvent">
<timerEventDefinition>
            <timeCycle>${expression}</timeCycle>
          
        </timerEventDefinition>
        </startEvent>    

<sequenceFlow sourceRef="startEvent" targetRef="workEvent"/>

        </serviceTask>
<endEvent id="endEvent"/>

That looks allright. Where do you set the expression variable?

public class SchedulingClassTest {
public static void main(String[] args) throws InterruptedException {
ProcessEngineConfiguration cfg = new StandaloneProcessEngineConfiguration()
.setJdbcUrl(“jdbc:h2:mem:flowable;DB_CLOSE_DELAY=-1”)
.setAsyncExecutorActivate(true)
.setJdbcUsername(“sa”)
.setJdbcPassword("")
.setJdbcDriver(“org.h2.Driver”)
.setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);//Process Engine Configuration
ProcessEngine processEngine = cfg.buildProcessEngine(); //Building Process Engine
RepositoryService repositoryService = processEngine.getRepositoryService();
org.flowable.engine.repository.Deployment deployment = repositoryService.createDeployment()
.addClasspathResource(“request.bpmn20.xml”)
.deploy(); //Deploying Process Definition
ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
.deploymentId(deployment.getId())
.singleResult();
String expression = “0 0 * ? * *”;
System.out.println("Found process definition : " + processDefinition.getName());//Printing name of Process Definition
Scanner scanner= new Scanner(System.in);
System.out.println(“Enter?”);
expression = scanner.nextLine();
RuntimeService runtimeService = processEngine.getRuntimeService();
runtimeService.setVariable(“startEvent”,“expression”,expression);

  }

}

What’s the “startEvent” parameter? That needs to be an executionId of the process instance.

Is exectionId = id we used for process definition

i have changed the line to runtimeService.setVariable(“workRequest”, “expression”,expression);
But error still comming

As the ‘expression’ is used for a start event, the ‘expression’ variable needs to be available right when the process instance is started. So you need to pass it when invoking runtimeService.startProcessInstanceByKey(“processKey”, variables);, where ‘variables’ is a Map containing the expression key/value.

i tried this-
runtimeService.startProcessInstanceById(“workRequest”, variables);
but still getting same error.
And I dont want to use runtimeService.startProcessInstanceById(“workRequest”, variables); because i am using timeCycle so the process should start itself at the particular time specified by cron expression.

Hower if I remove the $ sign from expression in xml then i get error-
Exception in thread “main” org.flowable.engine.common.api.FlowableException: Failed to parse cron expression: expression
at org.flowable.engine.impl.calendar.CycleBusinessCalendar.resolveDuedate(CycleBusinessCalendar.java:38)
at org.flowable.engine.impl.calendar.BusinessCalendarImpl.resolveDuedate(BusinessCalendarImpl.java:34)
at org.flowable.engine.impl.util.TimerUtil.createTimerEntityForTimerEventDefinition(TimerUtil.java:115)
at org.flowable.engine.impl.asyncexecutor.DefaultJobManager.createTimerJob(DefaultJobManager.java:108)
at org.flowable.engine.impl.bpmn.deployer.TimerManager.getTimerDeclarations(TimerManager.java:75)
at org.flowable.engine.impl.bpmn.deployer.TimerManager.scheduleTimers(TimerManager.java:58)
at org.flowable.engine.impl.bpmn.deployer.BpmnDeploymentHelper.updateTimersAndEvents(BpmnDeploymentHelper.java:153)
at org.flowable.engine.impl.bpmn.deployer.BpmnDeployer.updateTimersAndEvents(BpmnDeployer.java:212)
at org.flowable.engine.impl.bpmn.deployer.BpmnDeployer.deploy(BpmnDeployer.java:87)
at org.flowable.engine.impl.persistence.deploy.DeploymentManager.deploy(DeploymentManager.java:60)
at org.flowable.engine.impl.cmd.DeployCmd.executeDeploy(DeployCmd.java:116)
at org.flowable.engine.impl.cmd.DeployCmd.execute(DeployCmd.java:66)
at org.flowable.engine.impl.cmd.DeployCmd.execute(DeployCmd.java:40)
at org.flowable.engine.impl.interceptor.CommandInvoker$1.run(CommandInvoker.java:44)
at org.flowable.engine.impl.interceptor.CommandInvoker.executeOperation(CommandInvoker.java:86)
at org.flowable.engine.impl.interceptor.CommandInvoker.executeOperations(CommandInvoker.java:65)
at org.flowable.engine.impl.interceptor.CommandInvoker.execute(CommandInvoker.java:49)
at org.flowable.engine.impl.interceptor.TransactionContextInterceptor.execute(TransactionContextInterceptor.java:51)
at org.flowable.engine.impl.interceptor.CommandContextInterceptor.execute(CommandContextInterceptor.java:64)
at org.flowable.engine.impl.interceptor.LogInterceptor.execute(LogInterceptor.java:30)
at org.flowable.engine.impl.cfg.CommandExecutorImpl.execute(CommandExecutorImpl.java:56)
at org.flowable.engine.impl.cfg.CommandExecutorImpl.execute(CommandExecutorImpl.java:51)
at org.flowable.engine.impl.RepositoryServiceImpl.deploy(RepositoryServiceImpl.java:93)
at org.flowable.engine.impl.repository.DeploymentBuilderImpl.deploy(DeploymentBuilderImpl.java:188)
at SchedulingTest.SchedulingClassTest.main(SchedulingClassTest.java:34)
Caused by: java.text.ParseException: Illegal characters for this position: 'EXP’
at org.flowable.engine.impl.calendar.CronExpression.storeExpressionVals(CronExpression.java:428)
at org.flowable.engine.impl.calendar.CronExpression.buildExpression(CronExpression.java:334)
at org.flowable.engine.impl.calendar.CronExpression.(CronExpression.java:252)
at org.flowable.engine.impl.calendar.CycleBusinessCalendar.resolveDuedate(CycleBusinessCalendar.java:33)
… 24 more

Ok, I do see now.
The problem is that you can’t pass a variable to it, as the instance will be started by the system.

In that case, you should use a pojo or Spring bean so you can do ${someBean.giveMeMyExpression()}.
Note that you can reference any bean like that when you use Spring, but in other environments you need to pass the bean yourself: see Open Source

But what is the problem with runtimeService.setVariable(“workRequest”, variable);
And even if I am passing the variable in runtimeService.startProcessInstanceById(“workRequest”, variables); i am still getting same error

The problem is that you can only set variables on a running process instance. In this case, the instance hasn’t started yet (cause it will be started when the timer fires). I believe that “workRequest” is not your execution id, but your process definition id. Variables can only be set on process instances and executions.

What is execution id ?

Hi,

From reading all the previous posts, I think you should use a simple none start event and use an intermediate catch timer event after this start event. In this intermediate catch timer event you can use the expression like you describe and you can set the variable when starting the process instance.

Best regards,

Tijs

But then the Intermediate catch timer wont work as time cycle.
I tried using timecycle in intermediate catch event it only executes once and not as a timecycle.

Right, ok. That could be a feature request to add the time cycle capability to intermediate timer catch events as well. In the meantime there are 2 options I think. One is to loop back at the end of the process flow to the intermediate timer catch event, then you can use expressions. The other option is to use a (Spring) bean in your time cycle expression on a start event and let that bean calculate the time cycle value, instead of passing in a variable.

Best regards,

Tijs

1 Like