Spring boot DI with @Autowired for service class in serviceTask JavaDelegate

The exact problem I’m facing has a lot of posts around the internet with a lot of varying answers (some on this forum itself).

I am simply trying to use @Autowired to inject a service class into a JavaDelegate class with the flowable:class attribute on the serviceTask element. When I use this methodology, I get an NRE for my service class I’m trying to inject. If however, I use the flowable:delegateExpression attribute on my serviceTask element, everything works fine (the service class injection works correctly and I’m able to access its members within my execute() method on the delegate class. I would be satisfied using the delegateExpression methodology except for the fact that when I’m trying to create my flowable unit tests, the value in my delegateExpression can not be resolved but when I use a dummy delegate class and use flowable:class for the unit test, it works fine.

I’m nearly certain that I should be able to get the delegate class to work using flowable:class with the injected dependency because I’ve seen several people suggesting they sorted it out in the aforementioned posts. I’m wondering if perhaps a version change in either spring boot or flowable are the culprit here or if it’s a configuration setting that I’m missing.

From the research that I’ve done, I think the reason flowable:class is not working is because when using flowable:delegateExpression, Spring manages the lifecycle of the bean and so DI works as expected, but with flowable:class flowable is instantiating the class and so bypassing Spring’s lifecycle management. Again, perhaps this can be changed with a simple configuration setting that I’m just not aware of.

I have my component scanning set up in my application root to include both the packages of my delegate class and my service class. I have also added the Spring stereotype annotation to both my service class and my java delegate.

Here is all of the relevant code:

ApplicationRoot

package com.myorg.flowabledemo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;

@SpringBootApplication
@ComponentScan(basePackages = {
        "com.myorg.flowabledemo",
        "com.myorg.flowabledemo.serviceTasks",
        "com.myorg.flowabledemo.service"})
public class FlowableDemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(FlowableDemoApplication.class, args);
    }
}

BPMN (working with flowable:delegateExpression

        <serviceTask id="ServiceTaskAccountCheck" name="Service Task Account Check" flowable:delegateExpression="${checkAccountTypeServiceTask}">
        </serviceTask>

BPMN (failing with flowable:class)

        <serviceTask id="ServiceTaskAccountCheck" name="Service Task Account Check" flowable:class="com.myorg.flowabledemo.serviceTasks.CheckAccountTypeServiceTask">
        </serviceTask>

CommunicationService (service class I’m injecting with @Autowired)

package com.myorg.flowabledemo.service;

import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.HttpServerErrorException;
import org.springframework.web.client.RestTemplate;

@Service
public class CommunicationService {
   ....
}

CheckAccountTypeServiceTask (my java delegate class that needs to inject CommunicationService)

package com.myorg.flowabledemo.serviceTasks;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class CheckAccountTypeServiceTask implements JavaDelegate {

    @Autowired
    private CommunicationService communicationService;

    @Override
    public void execute(DelegateExecution delegateExecution) {
     ....
    }
}

I have tried using @Component and @Service on both my delegate class and communication service class - same result on both.

If anyone could shed some light on where I might be going wrong or what I’m missing that would be much appreciated.

EDIT: I have also tried a few other ways to pull in my CommunicationService class (using constructor injection, and ApplicationContext.getBean())

Hey @Burrito,

When you want to use Spring Beans in your models, then you should use delegateExpression. When using class, then Flowable will instantiate that class without the Spring context and thus @Autowired will not work.

Hope this helps,
Filip