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())