Run Camunda with Spring Boot on Wildfly

Hello there !

Hope all is well.

I am trying what should have been a simple thing to do, yet it has been driving me crazy all day long and I would appreciate all the help I can get.

I am trying to build a Camunda project based on the Java Spring Boot Integration. The main goal is to have some custom APIs that I build, on top the Camunda BPMN engine (and web apps).

When I run the project locally on my machine within the IDE (Intellij IDEA) as a Spring Boot application, it worked fine; I can call the custom APIs, open the web apps (cockpit / admin …).

When I generate a WAR file and deploy it on a Wildfly server, the deployments keep failing with the below error :

21:00:15,293 ERROR [org.jboss.msc.service.fail] (ServerService Thread Pool -- 91) MSC000001: Failed to start service jboss.deployment.unit."my-project-1.0.0-SNAPSHOT.war".undertow-deployment: org.jboss.msc.service.StartException in service jboss.deployment.unit."my-project-1.0.0-SNAPSHOT.war".undertow-deployment: java.lang.NullPointerException
        at org.wildfly.extension.undertow.deployment.UndertowDeploymentService$1.run(UndertowDeploymentService.java:81)
        at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
        at java.util.concurrent.FutureTask.run(Unknown Source)
        at org.jboss.threads.ContextClassLoaderSavingRunnable.run(ContextClassLoaderSavingRunnable.java:35)
        at org.jboss.threads.EnhancedQueueExecutor.safeRun(EnhancedQueueExecutor.java:1982)
        at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.doRunTask(EnhancedQueueExecutor.java:1486)
        at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1377)
        at java.lang.Thread.run(Unknown Source)
        at org.jboss.threads.JBossThread.run(JBossThread.java:485)
Caused by: java.lang.NullPointerException
        at org.jboss.resteasy.core.ConstructorInjectorImpl.<init>(ConstructorInjectorImpl.java:47)
        at org.jboss.resteasy.core.InjectorFactoryImpl.createConstructor(InjectorFactoryImpl.java:58)
        at org.jboss.resteasy.spi.ResteasyProviderFactory.injectedInstance(ResteasyProviderFactory.java:2836)
        at org.jboss.resteasy.core.interception.JaxrsInterceptorRegistry$AbstractInterceptorFactory.createInterceptor(JaxrsInterceptorRegistry.java:170)
        at org.jboss.resteasy.core.interception.JaxrsInterceptorRegistry$OnDemandInterceptorFactory.initialize(JaxrsInterceptorRegistry.java:188)
        at org.jboss.resteasy.core.interception.JaxrsInterceptorRegistry$OnDemandInterceptorFactory.checkInitialize(JaxrsInterceptorRegistry.java:203)
        at org.jboss.resteasy.core.interception.JaxrsInterceptorRegistry$OnDemandInterceptorFactory.getInterceptor(JaxrsInterceptorRegistry.java:214)
        at org.jboss.resteasy.core.interception.JaxrsInterceptorRegistry$AbstractInterceptorFactory.postMatch(JaxrsInterceptorRegistry.java:151)
        at org.jboss.resteasy.core.interception.JaxrsInterceptorRegistry.postMatch(JaxrsInterceptorRegistry.java:428)
        at org.jboss.resteasy.core.ResourceMethodInvoker.<init>(ResourceMethodInvoker.java:122)
        at org.jboss.resteasy.core.ResourceMethodRegistry.processMethod(ResourceMethodRegistry.java:351)
        at org.jboss.resteasy.core.ResourceMethodRegistry.register(ResourceMethodRegistry.java:278)
        at org.jboss.resteasy.core.ResourceMethodRegistry.addResourceFactory(ResourceMethodRegistry.java:229)
        at org.jboss.resteasy.core.ResourceMethodRegistry.addResourceFactory(ResourceMethodRegistry.java:201)
        at org.jboss.resteasy.core.ResourceMethodRegistry.addResourceFactory(ResourceMethodRegistry.java:187)
        at org.jboss.resteasy.core.ResourceMethodRegistry.addResourceFactory(ResourceMethodRegistry.java:164)
        at org.jboss.resteasy.core.ResourceMethodRegistry.addPerRequestResource(ResourceMethodRegistry.java:81)
        at org.jboss.resteasy.spi.ResteasyDeployment.registration(ResteasyDeployment.java:487)
        at org.jboss.resteasy.spi.ResteasyDeployment.startInternal(ResteasyDeployment.java:288)
        at org.jboss.resteasy.spi.ResteasyDeployment.start(ResteasyDeployment.java:93)
        at org.jboss.resteasy.plugins.server.servlet.ServletContainerDispatcher.init(ServletContainerDispatcher.java:140)
        at org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.init(HttpServletDispatcher.java:42)
        at io.undertow.servlet.core.LifecyleInterceptorInvocation.proceed(LifecyleInterceptorInvocation.java:117)
        at org.wildfly.extension.undertow.security.RunAsLifecycleInterceptor.init(RunAsLifecycleInterceptor.java:78)
        at io.undertow.servlet.core.LifecyleInterceptorInvocation.proceed(LifecyleInterceptorInvocation.java:103)
        at io.undertow.servlet.core.ManagedServlet$DefaultInstanceStrategy.start(ManagedServlet.java:305)
        at io.undertow.servlet.core.ManagedServlet.createServlet(ManagedServlet.java:145)
        at io.undertow.servlet.core.DeploymentManagerImpl$2.call(DeploymentManagerImpl.java:585)
        at io.undertow.servlet.core.DeploymentManagerImpl$2.call(DeploymentManagerImpl.java:556)
        at io.undertow.servlet.core.ServletRequestContextThreadSetupAction$1.call(ServletRequestContextThreadSetupAction.java:42)
        at io.undertow.servlet.core.ContextClassLoaderSetupAction$1.call(ContextClassLoaderSetupAction.java:43)
        at org.wildfly.extension.undertow.security.SecurityContextThreadSetupAction.lambda$create$0(SecurityContextThreadSetupAction.java:105)
        at org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1530)
        at org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1530)
        at org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1530)
        at org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1530)
        at io.undertow.servlet.core.DeploymentManagerImpl.start(DeploymentManagerImpl.java:598)
        at org.wildfly.extension.undertow.deployment.UndertowDeploymentService.startContext(UndertowDeploymentService.java:97)
        at org.wildfly.extension.undertow.deployment.UndertowDeploymentService$1.run(UndertowDeploymentService.java:78)
        ... 8 more

21:00:15,299 ERROR [org.jboss.as.controller.management-operation] (Controller Boot Thread) WFLYCTL0013: Operation ("deploy") failed - address: ([("deployment" => "my-project-1.0.0-SNAPSHOT.war")]) - failure description: {"WFLYCTL0080: Failed services" => {"jboss.deployment.unit.\"my-project-1.0.0-SNAPSHOT.war\".undertow-deployment" => "java.lang.NullPointerException
    Caused by: java.lang.NullPointerException"}}

Steps I have performed:

  1. I have selected the latest Camunda BPM Version at the time of writing (7.13.0)
  2. Spring Boot version is fixed on 2.2.5 by the Camunda BPM Initializr
  3. H2 Database is set as on disk.
  4. Java Version is set to 8.
  5. Camunda BPM Modules Rest API and Web Apps are checked.
  • I added <packaging>war</packaging> to the Maven POM file so I can build a WAR file.

  • I added the below dependency to the Maven POM file (to solve an error during the deployment on Wildfly).

    <dependency>
      <artifactId>spring-boot-starter-tomcat</artifactId>
      <groupId>org.springframework.boot</groupId>
      <scope>provided</scope>
    </dependency>
  • I added the below file to fix an issue related to Invalid HTTP Header Token :
package com.example.workflow.security;

import org.springframework.boot.web.servlet.ServletContextInitializer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class CsrfAutoConfiguration {
    private static final String CSRF_PREVENTION_FILTER = "CsrfPreventionFilter";
    /**
     * Overwrite csrf filter from Camunda configured here
     * org.camunda.bpm.spring.boot.starter.webapp.CamundaBpmWebappInitializer
     * org.camunda.bpm.spring.boot.starter.webapp.filter.SpringBootCsrfPreventionFilter
     * Is configured with basically a 'no-op' filter
     */
    @Bean
    public ServletContextInitializer csrfOverwrite() {
        return servletContext -> servletContext.addFilter(CSRF_PREVENTION_FILTER, (request, response, chain) -> chain.doFilter(request, response));
    }
}
  • I removed the camunda.bpm.admin-user provided. Doing so will simply make Camunda open the setup page on the first run.

  • I was able to successfully run the project locally as a Spring Boot application from within the Intellij IDEA IDE, it worked perfectly fine.

  • I perform a fresh download of Wildfly 19.0.0.Final ( from the official website ), extract it and run it by executing $WILDFLY_HOME\bin\standalone.bat ( I am running Windows 10).

  • I generated a WAR file and deployed it on a Wildfly server by copying the file $PROJECT_HOME\target\my-project-1.0.0-SNAPSHOT.war into $WILDFLY_HOME\standalone\deployments. The deployment will be automatically triggered and it will fail with error displayed at the top of the topic.

I have tried numerous trials and several work around but in vain, some of which :

  1. Using jboss-deployment-structure to disable jackson from Wildfly.
  2. Trying different versions of Spring Boot (2.3).
  3. Trying different versions of Wildfly (14 and 20).

You can directly check the project from https://github.com/FooElias/CamundaSpringBootSample/

Your help is much appreciated.

Many thank !

Hi @elias.sayegh.foo,

why did you choose this complicated structure?

It seems to me like: “I build my own car and want to drive it with a bus, but the car didn’t fit through the doors”.

If you want to use wildfly, you can try a maven overlay around this embedded engine with cockpit war file: https://docs.camunda.org/manual/7.13/installation/standalone-webapplication/

Or (more simple) skip the deployment to wildfly and run your application from the command line with java -jar my-camunda-spring-boot-app.jar.

Hope this helps, Ingo

2 Likes

Hello @Ingo_Richtsmeier, I am a colleague of @elias.sayegh.foo and we chose this structure because we want to communicate with camunda via its rest engine while still having access to the web applications of camunda. We also want to run java code related to camunda like delegate classes. If we are to deploy the standalone applications, how can we link camunda to our java delegate classes or the camunda SDK. Thank you so much for the help.

@Ingo_Richtsmeier pardon me, I forgot to add that we want wildfly specifically because that’s the webserver we are required to use in our project. Anything else would come as very cumbersome. Thanks again !

Hi @maroun_ayle and @elias.sayegh.foo,

OK, you have to…

We didn’t officially test it: https://docs.camunda.org/manual/7.13/user-guide/spring-boot-integration/#supported-deployment-scenarios

but this didn’t mean that it would not work.

I’ve found this tutorial: https://dzone.com/articles/deploying-spring-boot-app-to-jboss-wildfly where the author mentioned to extend a SpringBootServletInitializer.

This may match the NullPointerException you posted.

Hope this helps, Ingo

Hello @Ingo_Richtsmeier,

Much appreciated for the help !

We’ve already tried that (extending SpringBootServletInitializer, the repository was updated) but it made no difference (same issue). I am assuming the null pointer exception is occurring prior to the spring boot servlet initialization.

Is there any additional hints / pointers you can provide ?

I can only assume that our use case is rare and that most users consume Camunda differently.

Many thanks for your time and help.

Best regards.