Spring beans not injected into Flowable context

Hello, I’m trying to add Flowable into my project and I’m facing an issue when my Spring beans are not automatically added into Flowable context, therefore I cannot call them from by processes. From documentation and tests I understood this should work out of the box. Could you please advise if I’m doing something wrong / missing some configuration?
I’m using Flowable 6.3.1 and Spring Boot 2.0.2.

Flowable dependencies Pom:

        <dependency>
            <groupId>org.flowable</groupId>
            <artifactId>flowable-spring-boot-starter-rest</artifactId>
            <version>${flowable.version}</version>
        </dependency>
        <dependency>
            <groupId>org.flowable</groupId>
            <artifactId>flowable-http</artifactId>
            <version>${flowable.version}</version>
        </dependency>

My custom configuration class:

@Configuration
public class FlowableConfig implements EngineConfigurationConfigurer<SpringProcessEngineConfiguration> {
	@Override
	public void configure(SpringProcessEngineConfiguration config) {
             // custom form types here...
        }
}

Example of interface and bean, that does not get picked up by Flowable:

public interface PropertyService {
	String getValue(String property);
}

@Slf4j
@Component("propertyService")
public class PropertyServiceImpl implements PropertyService {

	private final Environment environment;

	@Autowired
	public PropertyServiceImpl(Environment environment) {
		this.environment = environment;
	}

	@Override
	public String getValue(String property) {
		String value = environment.getProperty(property);
		return value == null ? null : value.trim();
	}
}

This way I’d expect propertyService to be available in process expressions and script tasks (I’m using Groovy), however I’m always getting exception on missing property or bean.

Thanks for your time!

Hi,

Make sure that the package where you implemented the PropertyService is component scanned by Spring. Or you can create a @Bean method in the FlowableConfig class you created for example.

Best regards,

Tijs

Hi Tijs,

Thanks for your reply. The package is component scanned, I’ve also tried creating the service using @Bean factory as you suggested and the property service is still not accessible in the process…
The bean is 100% created as I can autowire it anywhere else and is also returned by Actuator in bean listing.

Is there any other catch or configuration I’m missing?

Thanks a lot! Kind Regards,
Jan

Hi, Did you ever get an answer to this question? I’m trying to do the same thing, and my beans are always null inside the JavaDelegate. tia, adym

Hi, didn’t make it work out of the box. My hacky solution was a bean post processor scanning all beans from certain packages and manually adding these to engine context.

Hi, I did get this to work, but I HAD to declare the beans within the Process Engine Configuration XML Element :

<bean 
    id="beanApproveTransaction" 
    class="com.lmig.ci.billing.tasks.ApproveTransaction">
    <property name="emailService" ref="emailService"/>
</bean>

<bean 
    id="beanEmailTask" 
    class="com.lmig.ci.billing.tasks.EmailTask">
    <property name="emailService" ref="emailService"/>
</bean>

<bean id="processEngineConfiguration"
    class="org.flowable.spring.SpringProcessEngineConfiguration">

    <property   name="dataSource"               ref="dataSource" />
    <property   name="transactionManager"       ref="transactionManager" />
    <property   name="databaseSchemaUpdate"     value="true" />
    <property   name="asyncExecutorActivate"    value="false" />

    <!-- 
    <property   name="deploymentResources"      value="classpath*:/xml/*.bpmn20.xml" />
     -->

    <property name="mailServerHost"             value="smtpin.lmig.com" />
    <property name="mailServerPort"             value="25" />

    <!--
    BEANS : Spring Beans integrated with the Flowable Engine 
            <entry key="beanEmailService"       value-ref="emailService" />
    -->
    <property name="beans">
        <map>
            <entry key="beanApproveTransaction" value-ref="beanApproveTransaction" />
            <entry key="beanEmailTask"          value-ref="beanEmailTask" />
        </map>
    </property>
</bean>

hth,

adym

Hello,

The same for me.
Impossible to retrieve Flowable beans (ProcessEngine, TaskService…) in my JavaDelegate class (declared as @Service) called by a Service Task.
For example, @Autowired TaskService defined in my Spring configuration file (declared as @Configuration) returns a TaskService object when it returns null in the JavaDelegate.
And no way to find an example on the Flowable forum or anywhere else on the net. :frowning:
Remark: I use flowable embedded in a spring boot application.

Thanks for your help
Best Regards
William

Hello, I have the same issue. Is there an annotations based work-around for this?
I’d really like to inject the resource that the delegate needs rather than some other hack.
Thanks,
Eric

Here is the work-around I found in a related post somewhere…

Define the beans in the application class

@SpringBootApplication
public class DeckServiceApplication {
    public static void main(String[] args) {
        SpringApplication.run(DeckServiceApplication.class, args);
    }
    @Bean
    public MotionServerClient getMotionServerClient(@Value("${devices.motion.host}") String host, @Value("${devices.motion.port}") int port) {
        MotionServerClient motionServerClient = new MotionServerClient(host, port);
        return motionServerClient;
    }
    @Bean
    public BarcodeServerClient getBarcodeServerClient(@Value("${devices.barcode.host}") String host, @Value("${devices.barcode.port}") int port) {
        BarcodeServerClient barcodeServerClient = new BarcodeServerClient(host, port);
        return barcodeServerClient;
    }
}

Create an initializer component that saves the beans to a static utility using a @PostConstruct method

@Component
public final class DeviceClientFactoryInitializer {
    @Autowired
    private MotionServerClient motionServerClient;
    @Autowired
    private BarcodeServerClient barcodeServerClient;
    @PostConstruct
    public void init() {
        DeviceClientUtil.setMotionServerClient(motionServerClient);
        DeviceClientUtil.setBarcodeServerClient(barcodeServerClient);
    }
}

Access the beans in the Flowable referenced listeners or executions using the static utility methods

public class DeviceClientUtil {
    private static MotionServerClient motionServerClient;
    private static BarcodeServerClient barcodeServerClient;
    
    private DeviceClientUtil() {}

    public static MotionServerClient getMotionServerClient() {
        return motionServerClient;
    }
    public static BarcodeServerClient getBarcodeServerClient() {
        return barcodeServerClient;
    }
    public static void setMotionServerClient(MotionServerClient client) {
        DeviceClientUtil.motionServerClient = client;
    }
    public static void setBarcodeServerClient(BarcodeServerClient client) {
        DeviceClientUtil.barcodeServerClient = client;
    }
}
private ManagementService getManagementService() {
    return (ManagementService) AppContext.getApplicationContext().getBean(ManagementService.class);
}

If the bean is a singleton, you can make the field static and inject it in the usual way.