Acessing Spring @Service class instance in Java Delegate execute method

I’ve seen various forms of this question asked with different answers so I just want to clarify my issue here, apologies if I’ve misinterpreted a previous answer.

I’ve got a Java Delegate implementation that looks like this:

package com.jonathan.delegates

public class SetAttributes implements JavaDelegate {
    @Autowired
    AttributeService attributeService;
        
    @Override
    public void execute(DelegateExecution execution) {
        //prepare attributes for service in some code here

        attributeService.run(attributes) 
    }
}

My problem is when execute gets called using flowable:class, the attributeService object is null, Spring is initializing other @Service annotated classes throughout the application without issues, including instances of the AttributeService
flowable:class="com.jonathan.delegates.SetAttributes">

Some examples I’ve seenI should be passing off execution to SetAttributes via a flowable:delegateExpression="${setAttributes}

Others I’m seeing implementations where SetAttributes doesn’t implement JavaDelegate at all and is declared with @Component (or @Service) annotation, then a method is created with a DelegateExecution parameter and then called something like this:
flowable:delegate="#{setAttributes.method(execution)}"

None of these have worked for me, and other than my initial implementation which gives the null pointer exception while attempting to access the service, there’s not a lot of information in my logs.

2 Likes

Can you describe your setup a little. Are you trying to use your delegates by adding a library to the Task or Rest WAR or are you using your own spring application.

flowable:class simply instantiates an instance of the class (via new) and calls the method. It is not spring aware, so you’re getting null pointer exceptions.

flowable:expression and flowable:delegateExpression evaluate expressions with expression simply executing the expression and delegateExpression expecting a bean that implements JavaDelegate.

If you are attempting to call your delegate from one of the prebuilt WARs, you have to enable auto-configuration on the library so that your beans will be in the spring context https://flowable.org/docs/userguide/index.html#custom-bean-deployment

I am using my own Spring application, so this result definitely makes a lot of sense/is what I expected based on reading.

After re-reading your posts, I’ve managed to get it working by adding the bean to my configuration class. I made the mistake of annotating the bean with @Component which I think may have been causing issues.

Thanks again!

No problem,

Many (most) Spring Boot applications have component scanning turned on, so annotating the classes with @Component or @Service is sufficient to get them into the Spring context. If you’ve turned off component scanning or limited its scope, you may have to manually add the delegates to your configuration or explicitly scan the package that they are in.

This can be solved by placing the java delegate and AttributeService on the proper base scan package. But the issue happens , when AttributeService has another @Autowired object, it is not getting injected and the system will throw an error.

You can always get the Bean from the App context…
public AttributeService getComponentUtils(){
return (AttributeService)AppContext.getApplicationContext().getBean(AttributeService.class);
}

1 Like