Wildfly: configuring shared-managed process engine's services as spring beans programmatically

Hi,

I am having trouble trying to configure the Process engine services as Spring beans in a Spring web app that I run on Wildfly10.

I understand that the problem is the race condition described here:
https://docs.camunda.org/manual/7.6/user-guide/runtime-container-integration/jboss/#manage-service-dependencies

However try as I might I can’t figure out how to do it properly so would greatly appreciate any help.

All the configuration is done programmatically.

The SpringWebInitializer:

public class SpringWebInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class[] { SpringWebConfig.class };
    }

    @Override
    protected String[] getServletMappings() {
        return new String[] { "/" };
    }

    @Override
    protected Class<?>[] getRootConfigClasses() {
        return null;
    }
}

The actual SpringWebConfig

@EnableWebMvc //mvc:annotation-driven
@Configuration
@ComponentScan({ "com.economical.ecosystem.camunda" })
public class SpringWebConfig extends WebMvcConfigurerAdapter {
    @Bean(name="processApplication")
    public SpringServletProcessApplication processApplication() {
        return new SpringServletProcessApplication();
    }

    @Bean(name="processEngineService")
    public ProcessEngineService processEngineService(@Autowired SpringServletProcessApplication app) {
        return BpmPlatform.getProcessEngineService();
    }

    @Bean(name="processEngine")
    public ProcessEngine processEngine(@Autowired ProcessEngineService processEngineService) {
        return processEngineService.getDefaultProcessEngine();
    }

    @Bean
    public RuntimeService runtimeService(@Autowired ProcessEngine processEngine) {
        return processEngine.getRuntimeService();
    }

    @Bean
    public RepositoryService repositoryService(@Autowired ProcessEngine processEngine) {
        return processEngine.getRepositoryService();
    }

    @Bean
    public TaskService taskService(@Autowired ProcessEngine processEngine) {
        return processEngine.getTaskService();
    }

    @Bean
    public HistoryService historyService(@Autowired ProcessEngine processEngine) {
        return processEngine.getHistoryService();
    }
}

The SpringServletProcessApplication is a custom one, implemented it after this sample
[Spring shared process engine getting started example does not deploy]
(Spring shared process engine getting started example does not deploy)

@ProcessApplication
public class SpringServletProcessApplication extends ServletProcessApplication {

    @PostDeploy
    public void startProcess(ProcessEngine processEngine) {
        System.out.println("Invoking @PostDeploy annotation in " + getClass().getName());
    }

    @PreUndeploy
    public void remove() {
        System.out.println("Invoking @PreUndeploy annotation in " + getClass().getName());
        System.out.println("Undeploying SpringServletProcessApplication-Example");
    }
}

The initialization of the service beans happens before the shared engine is actually available so geting an NPE:

Caused by: java.lang.NullPointerException
        at com.economical.ecosystem.camunda.config.SpringWebConfig.repositoryService(SpringWebConfig.java:51)

I’ve also tried getting the process engine through JNDI, that fails too for the same reason -the shared engine isn’t yet initialized and registered with JNDI.

Hope I am missing something simple here, thanks a lot in advance for the assistance.

Thanks,
Andrey.

If you’re using WildFly10… why not just use CDI?

I have lots of examples if interested. And, RedHat also has some good ‘quickstart’ (though not exactly robust) examples.

Hi Gary,

Thanks for the reply.

We’re using Spring MVC, a standard for our Web API projects at the moment - and this particular app is an extension of the Camunda REST API.

Also we’re using Tomcat for the local development and Wildfly for QA/Stage/etc. so the app should work in both containers.
I guess we can install CDI on our dev Tomcats but that’s extra work we’d like to avoid ideally.
The original problem doesn’t to happen in tomcats btw.

Thanks,
Andrey.

I use Wildfly for both local and server. But, I can see the point to keeping Spring.

Wouldn’t recommend installing CDI into Tomcat when you can download (or build via Camunda’s pom.xml) a full WildFly platform.

I did finally start using Tomcat for CMS/Document-management. The big open-source CMS is really glued into CXF. And, Wildfly uses ReSTEasy. But, if you’re already porting to RestEasy that shouldn’t be an issue.

We did consider using RestEasy, even built a prototype, but ultimately chose Spring to be consistent since we use it in other projects and didn’t want to migrate them.

And we’re using the pre-built WildFly indeed which we customize somewhat including this extra Camudna API we’re developing now.