Adding Dynamic Task at runtime using DynamicUserTaskBuilder and DynamicBpmnService

I have created a simple process model, which consists of two user tasks. I wanted to add one more user task at runtime. I am trying to create one, using DynamicUserTaskBuilder. And then now, I am trying to inject this user task in my process instance. But, the problem is, it gives me error while injecting.

The ERROR occurs on line :
dynamicBpmnService.injectUserTaskInProcessInstance(processInstance.getProcessInstanceId(), taskBuilder);

Please find the same in the below code snippet.

This is my code snippet :

import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

import org.flowable.bpmn.model.BpmnModel;
import org.flowable.bpmn.model.FlowElement;
import org.flowable.bpmn.model.Process;
import org.flowable.bpmn.model.SequenceFlow;
import org.flowable.engine.DynamicBpmnService;
import org.flowable.engine.RepositoryService;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.TaskService;
import org.flowable.engine.impl.dynamic.DynamicUserTaskBuilder;
import org.flowable.engine.repository.Model;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.task.api.Task;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;


@Service
public class MyService {
	Logger logger=LoggerFactory.getLogger(MyService.class);
	
	@Autowired
	public RuntimeService runtimeService;
	
	@Autowired
	TaskService taskService;
	
	@Autowired
	DynamicBpmnService dynamicBpmnService;
	
	@Autowired
	RepositoryService repositoryService;
	
	Scanner sc = new Scanner(System.in);

	
	public void startProcess() {
		
		logger.info("In Start Service: MY Before startProcess..!!!");	
		ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("AddingDynamicUserTaskKey");
		
		
		//GIVING SOME FUNCTIONALITY TO THE PREVIOUSLY CREATED USER TASK 1.......
		Task task1 = taskService.createTaskQuery().processInstanceId(processInstance.getId()).taskDefinitionKey("UserTask1Id").singleResult();		
		task1.setName("One Direction");
		System.out.println("Greatest Boy band  -  " +task1.getName());
		taskService.complete(task1.getId());
		
		System.out.println("Somewhere between two processes...");
		
		
		
		
		//CREATING OUR OWN USER SERVICE TASK......
		
		DynamicUserTaskBuilder taskBuilder = new DynamicUserTaskBuilder();
		System.out.println("DynamicUserTaskBuilder ------- 1");
		
		taskBuilder.id("MyTempId4")
		.name("MyTempTaskName4")
		.assignee("Krishnakant4");
			
		dynamicBpmnService.injectUserTaskInProcessInstance(processInstance.getProcessInstanceId(), taskBuilder);

		System.out.println("HEY..Maybe you new User Task is created...Need to verify! ");
		System.out.println("New User Task Name Is : "+ taskBuilder.getName());
			
		
	
		
		//GIVING SOME FUNCTIONALITY TO THE PREVIOUSLY CREATED USER TASK 2.......
		Task task2 = taskService.createTaskQuery().processInstanceId(processInstance.getId()).taskDefinitionKey("UserTask2Id").singleResult();	
		if(task2 != null) {
			task2.setName("Lionel Messi");
			System.out.println("Greatest of all time  -  " +task2.getName());
		}	
		taskService.complete(task2.getId());
				
	
		logger.info("MY After StartProcess..!!!");
		
	}

}

Below is the error after running the snippet file :

 2020-03-17 12:56:21.559  INFO 22124 --- [nio-8998-exec-1] c.k.flowable.services.MyService          : In Start Service: MY Before startProcess..!!!
Greatest Boy band  -  One Direction
Somewhere between two processes...
DynamicUserTaskBuilder ------- 1
ERROR:  'ParseError at [row,col]:[5,163]
Message: http://www.w3.org/TR/1999/REC-xml-names-19990114#AttributeNSNotUnique?userTask&formFieldValidation&http://flowable.org/bpmn'
2020-03-17 12:56:26.948 ERROR 22124 --- [nio-8998-exec-1] o.f.e.i.b.d.ParsedDeploymentBuilder      : Could not parse resource C:\Users\KV0C85403\Documents\workspace-spring-tool-suite-4-4.3.0.RELEASE\flowableapiAddingDynamicUserTask\target\classes\processes\AddingDynamicUserTask.bpmn20.xml

org.flowable.bpmn.exceptions.XMLException: javax.xml.stream.XMLStreamException: ParseError at [row,col]:[5,163]
Message: http://www.w3.org/TR/1999/REC-xml-names-19990114#AttributeNSNotUnique?userTask&formFieldValidation&http://flowable.org/bpmn
	at org.flowable.bpmn.converter.BpmnXMLConverter.convertToBpmnModel(BpmnXMLConverter.java:275) ~[flowable-bpmn-converter-6.4.2.jar:6.4.2]
	at org.flowable.engine.impl.bpmn.parser.BpmnParse.execute(BpmnParse.java:148) ~[flowable-engine-6.4.2.jar:6.4.2]
	at org.flowable.engine.impl.bpmn.deployer.ParsedDeploymentBuilder.createBpmnParseFromResource(ParsedDeploymentBuilder.java:97) [flowable-engine-6.4.2.jar:6.4.2]
	at org.flowable.engine.impl.bpmn.deployer.ParsedDeploymentBuilder.build(ParsedDeploymentBuilder.java:55) [flowable-engine-6.4.2.jar:6.4.2]
	at org.flowable.engine.impl.bpmn.deployer.BpmnDeployer.deploy(BpmnDeployer.java:78) [flowable-engine-6.4.2.jar:6.4.2]
	at org.flowable.engine.impl.cmd.AbstractDynamicInjectionCmd.deployDerivedDeploymentEntity(AbstractDynamicInjectionCmd.java:107) [flowable-engine-6.4.2.jar:6.4.2]
	at org.flowable.engine.impl.cmd.AbstractDynamicInjectionCmd.createDerivedProcessDefinition(AbstractDynamicInjectionCmd.java:60) [flowable-engine-6.4.2.jar:6.4.2]
	at org.flowable.engine.impl.cmd.AbstractDynamicInjectionCmd.createDerivedProcessDefinitionForProcessInstance(AbstractDynamicInjectionCmd.java:52) [flowable-engine-6.4.2.jar:6.4.2]
	at org.flowable.engine.impl.cmd.InjectUserTaskInProcessInstanceCmd.execute(InjectUserTaskInProcessInstanceCmd.java:50) [flowable-engine-6.4.2.jar:6.4.2]
	at org.flowable.engine.impl.cmd.InjectUserTaskInProcessInstanceCmd.execute(InjectUserTaskInProcessInstanceCmd.java:38) [flowable-engine-6.4.2.jar:6.4.2]
	at org.flowable.engine.impl.interceptor.CommandInvoker$1.run(CommandInvoker.java:51) [flowable-engine-6.4.2.jar:6.4.2]
	at org.flowable.engine.impl.interceptor.CommandInvoker.executeOperation(CommandInvoker.java:93) [flowable-engine-6.4.2.jar:6.4.2]
	at org.flowable.engine.impl.interceptor.CommandInvoker.executeOperations(CommandInvoker.java:72) [flowable-engine-6.4.2.jar:6.4.2]
	at org.flowable.engine.impl.interceptor.CommandInvoker.execute(CommandInvoker.java:56) [flowable-engine-6.4.2.jar:6.4.2]
	at org.flowable.engine.impl.interceptor.BpmnOverrideContextInterceptor.execute(BpmnOverrideContextInterceptor.java:25) [flowable-engine-6.4.2.jar:6.4.2]
	at org.flowable.common.engine.impl.interceptor.TransactionContextInterceptor.execute(TransactionContextInterceptor.java:53) [flowable-engine-common-6.4.2.jar:6.4.2]
	at org.flowable.common.engine.impl.interceptor.CommandContextInterceptor.execute(CommandContextInterceptor.java:72) [flowable-engine-common-6.4.2.jar:6.4.2]
	at org.flowable.common.spring.SpringTransactionInterceptor.lambda$execute$0(SpringTransactionInterceptor.java:56) [flowable-spring-common-6.4.2.jar:6.4.2]
	at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:140) ~[spring-tx-5.2.4.RELEASE.jar:5.2.4.RELEASE]
	at org.flowable.common.spring.SpringTransactionInterceptor.execute(SpringTransactionInterceptor.java:56) [flowable-spring-common-6.4.2.jar:6.4.2]
	at org.flowable.common.engine.impl.interceptor.LogInterceptor.execute(LogInterceptor.java:30) ~[flowable-engine-common-6.4.2.jar:6.4.2]
	at org.flowable.common.engine.impl.cfg.CommandExecutorImpl.execute(CommandExecutorImpl.java:56) ~[flowable-engine-common-6.4.2.jar:6.4.2]
	at org.flowable.common.engine.impl.cfg.CommandExecutorImpl.execute(CommandExecutorImpl.java:51) ~[flowable-engine-common-6.4.2.jar:6.4.2]
	at org.flowable.engine.impl.DynamicBpmnServiceImpl.injectUserTaskInProcessInstance(DynamicBpmnServiceImpl.java:51) ~[flowable-engine-6.4.2.jar:6.4.2]
	at com.krishnakant.flowable.services.MyService.startProcess(MyService.java:84) ~[classes/:na]
	at com.krishnakant.flowable.controller.MyController.startProcessInstance(MyController.java:23) ~[classes/:na]
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_191]
	at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_191]
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_191]
	at java.lang.reflect.Method.invoke(Unknown Source) ~[na:1.8.0_191]
	at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190) ~[spring-web-5.2.4.RELEASE.jar:5.2.4.RELEASE]
	at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138) ~[spring-web-5.2.4.RELEASE.jar:5.2.4.RELEASE]
	at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:106) ~[spring-webmvc-5.2.4.RELEASE.jar:5.2.4.RELEASE]
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:879) ~[spring-webmvc-5.2.4.RELEASE.jar:5.2.4.RELEASE]
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:793) ~[spring-webmvc-5.2.4.RELEASE.jar:5.2.4.RELEASE]
	at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.2.4.RELEASE.jar:5.2.4.RELEASE]
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1040) ~[spring-webmvc-5.2.4.RELEASE.jar:5.2.4.RELEASE]
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943) ~[spring-webmvc-5.2.4.RELEASE.jar:5.2.4.RELEASE]
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) ~[spring-webmvc-5.2.4.RELEASE.jar:5.2.4.RELEASE]
	at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898) ~[spring-webmvc-5.2.4.RELEASE.jar:5.2.4.RELEASE]
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:634) ~[tomcat-embed-core-9.0.31.jar:9.0.31]
	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) ~[spring-webmvc-5.2.4.RELEASE.jar:5.2.4.RELEASE]
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:741) ~[tomcat-embed-core-9.0.31.jar:9.0.31]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) ~[tomcat-embed-core-9.0.31.jar:9.0.31]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.31.jar:9.0.31]
	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) ~[tomcat-embed-websocket-9.0.31.jar:9.0.31]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.31.jar:9.0.31]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.31.jar:9.0.31]
	at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-5.2.4.RELEASE.jar:5.2.4.RELEASE]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.4.RELEASE.jar:5.2.4.RELEASE]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.31.jar:9.0.31]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.31.jar:9.0.31]
	at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-5.2.4.RELEASE.jar:5.2.4.RELEASE]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.4.RELEASE.jar:5.2.4.RELEASE]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.31.jar:9.0.31]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.31.jar:9.0.31]
	at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-5.2.4.RELEASE.jar:5.2.4.RELEASE]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.4.RELEASE.jar:5.2.4.RELEASE]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.31.jar:9.0.31]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.31.jar:9.0.31]
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202) ~[tomcat-embed-core-9.0.31.jar:9.0.31]
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) ~[tomcat-embed-core-9.0.31.jar:9.0.31]
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541) ~[tomcat-embed-core-9.0.31.jar:9.0.31]
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139) ~[tomcat-embed-core-9.0.31.jar:9.0.31]
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) ~[tomcat-embed-core-9.0.31.jar:9.0.31]
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) ~[tomcat-embed-core-9.0.31.jar:9.0.31]
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) ~[tomcat-embed-core-9.0.31.jar:9.0.31]
	at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:367) ~[tomcat-embed-core-9.0.31.jar:9.0.31]
	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) ~[tomcat-embed-core-9.0.31.jar:9.0.31]
	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868) ~[tomcat-embed-core-9.0.31.jar:9.0.31]
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1639) ~[tomcat-embed-core-9.0.31.jar:9.0.31]
	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) ~[tomcat-embed-core-9.0.31.jar:9.0.31]
	at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) ~[na:1.8.0_191]
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) ~[na:1.8.0_191]
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-9.0.31.jar:9.0.31]
	at java.lang.Thread.run(Unknown Source) ~[na:1.8.0_191]
Caused by: org.xml.sax.SAXException: javax.xml.stream.XMLStreamException: ParseError at [row,col]:[5,163]

Please let me know if I’m missing out something as soon as possible.

regards
Krishnakant

Hey @modanikv,

There is an example for this here:

Can you please share your entire stacktrace and provide a reproducible test case that we can try out?

Cheers,
Filip

Hey @filiphr,

Thanks for the reply.
I have referred and tried the same code snippet as above.
I have already provided my complete code snippet, as well as the stack trace of error above. Have even mentioned where exactly the error occurs(by providing simple print statements for debugging).
It gives error on injecting. I have been running this code as a spring boot application. Is it something else you need?

regards,
Krishnakant

There is something from the stacktrace missing. it ends with

Caused by: org.xml.sax.SAXException: javax.xml.stream.XMLStreamException: ParseError at [row,col]:[5,163]

There should be more under that.

Can you give us access to the Spring Boot application or put it on GitHub so we can try it out? We need the BPMN XML as well

hi filiohr
I have another question. In the provided interface, there are only id, name and assigne for the dynamic userTask attribute setting. If I want to set more attributes for the dynamicusertaskBuilder,
Do you have any suggestions?

regards
Kelly

That builder API has a dynamicUserTaskCallback that can be set. In it, you get the UserTask object on which other properties can be set.

Hi @filiphr, @joram

Once I create a dynamic user task and mark it complete, I want it to go to next level to supervisor for approval or rejection.how can I do it programmatically at runtime?is there any example which shows setting sequence flow.i want the task to go to a particular group and not to an individual.i added candidate group but it’s not working.i mean approved don’t see this task.

I think once original task is complete, I can create another user task and put candidate group as supervisor but this will not maintain flow history.i want it to work as once flow.

I have requirement of adding multiple task at runtime.user will finish all task and than mark all task as complete.once done, all task must move to supervisor.