Inject ProcessInstance in SpringBoot Application

Hi there,

we are using https://github.com/camunda/camunda-bpm-spring-boot-starter to run camunda within an spring-boot environment.

We try to use the accessorPattern and therefore want to inject the current running ProcessInstance into our accessor:

Bpmn:
<bpmn:userTask id="UserTask_edit" name="Task bearbeiten" camunda:formKey="edit_task" camunda:candidateGroups="#{UserTask.clientGroup}"> <bpmn:extensionElements> <camunda:taskListener delegateExpression="${taskNotificationListener}" event="create" /> </bpmn:extensionElements>


Accessor (wip):

@Component("UserTask")
@Scope(value = "prototype", proxyMode = ScopedProxyMode.TARGET_CLASS)
public class UserTaskAccessor {

@Inject
ProcessInstance processInstance;

public String getClientGroup() {

	// read ProcessVariable 'clientId' from PI
	// load agency from client
	// agency == UserGroup
	return "BLA";
}

}

Our TestCase:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = {TestRepositoryConfig.class,
    CamundaBpmAutoConfiguration.class, TestMessagingConfig.class})
@Transactional
public class ProcessInstanceTest {

  @Autowired
  ProcessInstanceService piService;

  @Autowired
  public ProcessEngine processEngine;

  @Deployment
  @Test
  public void testSimpleProcess() {

    ProcessInstance pi = piService.startInstanceByKey("test-process", "1234", null);

    RuntimeService runtimeService = processEngine.getRuntimeService();
    TaskService taskService = processEngine.getTaskService();
    Task task = taskService.createTaskQuery().taskCandidateGroup("BLA").singleResult();
    assertEquals("Task bearbeiten", task.getName());

    Map<String, Object> procVars = new HashMap<>();
    procVars.put("freigabe", Boolean.TRUE);

    taskService.complete(task.getId(), procVars);
    assertEquals(0, runtimeService.createProcessInstanceQuery().count());


  }

But currently i get the following error:

Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: org.camunda.bpm.engine.runtime.ProcessInstance com.floatware.danube.accessors.UserTaskAccessor.processInstance; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.camunda.bpm.engine.runtime.ProcessInstance] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@javax.inject.Inject()}
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:573)
	at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:331)
	... 144 more
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.camunda.bpm.engine.runtime.ProcessInstance] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@javax.inject.Inject()}
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:1373)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1119)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1014)
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:545)
	... 146 more

Are we doing something wrong, or is it not possible to inject the processInstance in an spring-boot environment?

Thanks and all the best
Jürgen

Guess is is not possible :expressionless:

Anyway for the sake of documentation:
I “solved” it the old fashioned way by passing the delegateExecution into my method:

@Component("UserTask")
public class UserTaskAccessor extends DanubeAccessor {

  public String getAssignedRoleFromClient(DelegateExecution execution) {
      // fetch vars from execution
     //  load client usw...
  }
 Object getProcessVariable(String name, DelegateExecution e) {
    return e.getProcessInstance().getVariable(name);
  }
}

Cheers
Jürgen

You are right, this is not possible. It’s not starter specific, there is just now way of knowing the execution context without passing “something” to the delegate.

engine-cdi has a “contextual programming model” that uses an AssociationManager to connect the delegate to the processInstance. But that whole concept was never adapted to engine-spring.

Thank you for your explanation.

Cheers
Jürgen