Cannot access camunda CDI beans from Spring

949 views
Skip to first unread message

Jakob Schubert

unread,
Jun 1, 2015, 8:32:51 AM6/1/15
to camunda-...@googlegroups.com

Hello

I try to use camunda bpm version 7.2.0 in a large Spring/JSF application, where the JSF backing beans are managed by Spring. I have successfully configured the camunda-engine with Spring, but I am not able to access CDI beans from the application in different scenarios:  
a) injecting a org.camunda.bpm.engine.cdi.BusinessProcess  bean in a Spring bean results in a NoSuchBeanDefinitionException during initialization of the Spring application context (cf. the full stacktrace below). 
b) accessing org.camunda.bpm.engine.cdi.compat.CamundaTaskForm from a JSF page results in an exception "Target Unreachable, identifier 'camundaTaskForm' resolved to null" when I call the corresponding page (cf. the stacktrace below).

The module camunda-engine-cdi is on the classpath, and I have added an (empty) beans.xml in the WEB-INF resp. META-INF folders in my project. 

What else is necessary in order to access the camunda CDI beans from my Spring application? 

Thanks
Jakob Schubert

Stacktrace a) 

[2015-06-01 14:05:32,346] [localhost-startStop-1] WARN  org.springframework.web.context.support.XmlWebApplicationContext refresh - corid= Exception encountered during context initialization - cancelling refresh attempt
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'approveOrderController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.camunda.bpm.engine.cdi.BusinessProcess ch.sbb.myapp.presentation.bpmn.ApproveOrderController.businessProcess; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.camunda.bpm.engine.cdi.BusinessProcess] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@javax.inject.Inject()}
        at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:326)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1204)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:538)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
        at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:302)
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:229)
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298)
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:725)
        at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:757)
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:480)
        at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:403)
        at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:306)
        at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:106)
        at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4797)
        at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5291)
        at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
        at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1559)
        at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1549)
        at java.util.concurrent.FutureTask.run(FutureTask.java:273)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1176)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
        at java.lang.Thread.run(Thread.java:795)
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.camunda.bpm.engine.cdi.BusinessProcess ch.sbb.myapp.presentation.bpmn.ApproveOrderController.businessProcess; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.camunda.bpm.engine.cdi.BusinessProcess] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@javax.inject.Inject()}
        at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:542)
        at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
        at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:323)
        ... 22 more
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.camunda.bpm.engine.cdi.BusinessProcess] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@javax.inject.Inject()}
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:1261)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1009)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:904)
        at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:514)
        ... 24 more


Stacktrace b) 

Jun 01, 2015 1:58:16 PM org.apache.catalina.core.StandardWrapperValve invoke
SCHWERWIEGEND: Servlet.service() for servlet [Faces Servlet] in context with path [/template-web-jsf] threw exception [/pages/bpmn/placeorder.xhtml @20,103 listener="#{camundaTaskForm.startProcessInstanceByKeyForm()}": Target Unreachable, identifier 'camundaTaskForm' resolved to null] with root cause
javax.el.PropertyNotFoundException: /pages/bpmn/placeorder.xhtml @20,103 listener="#{camundaTaskForm.startProcessInstanceByKeyForm()}": Target Unreachable, identifier 'camundaTaskForm' resolved to null
        at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:107)
        at com.sun.faces.facelets.tag.jsf.core.DeclarativeSystemEventListener.processEvent(EventHandler.java:128)
        at javax.faces.component.UIComponent$ComponentSystemEventListenerAdapter.processEvent(UIComponent.java:2584)
        at javax.faces.event.SystemEvent.processListener(SystemEvent.java:108)
        at javax.faces.event.ComponentSystemEvent.processListener(ComponentSystemEvent.java:118)
        at com.sun.faces.application.ApplicationImpl.processListeners(ApplicationImpl.java:2169)
        at com.sun.faces.application.ApplicationImpl.invokeComponentListenersFor(ApplicationImpl.java:2114)
        at com.sun.faces.application.ApplicationImpl.publishEvent(ApplicationImpl.java:287)
        at com.sun.faces.application.ApplicationImpl.publishEvent(ApplicationImpl.java:245)
        at javax.faces.application.ApplicationWrapper.publishEvent(ApplicationWrapper.java:726)
        at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:107)
        at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
        at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:219)
        at javax.faces.webapp.FacesServlet.service(FacesServlet.java:647)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
        at org.springframework.web.filter.AbstractRequestLoggingFilter.doFilterInternal(AbstractRequestLoggingFilter.java:214)
        at ch.sbb.esta.util.web.ServletContextRequestLoggingFilter.doFilterInternal(ServletContextRequestLoggingFilter.java:39)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
        at ch.sbb.esta.util.web.cachepolicy.EstaCacheControlFilter.doFilter(EstaCacheControlFilter.java:85)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
        at ch.sbb.esta.service.implicitcontext.web.ImplicitContextPassingFilter.doFilterInternal(ImplicitContextPassingFilter.java:55)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
        at org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter.doFilterInternal(OpenEntityManagerInViewFilter.java:177)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
        at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
        at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:581)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
        at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:936)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
        at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1004)
        at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
        at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1176)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
        at java.lang.Thread.run(Thread.java:795)

Ronny Bräunlich

unread,
Jun 2, 2015, 2:24:40 AM6/2/15
to camunda-...@googlegroups.com, jakob.s...@gmail.com
Hello Jakob,

just to start at the beginning, why do you want to access CDI beans from Spring?
Usually CDI and Spring don't work so well together because both want to do the same and have control over the beans. Also they don't share anything.
Generally, I guess it is not so easy to bridge that gap (Apache DeltaSpike plans to do this see [1]).

Did you manage somewhere else in your application to access CDI beans from Spring beans? Or is this something new you try to achieve?
Which environment (Tomcat, JBoss,...) do you use?

Cheers,
Ronny

[1] https://cwiki.apache.org/confluence/display/DeltaSpike/Spring+CDI+integration

jakob.s...@gmail.com

unread,
Jun 2, 2015, 7:30:28 AM6/2/15
to camunda-...@googlegroups.com, jakob.s...@gmail.com
Hi Ronny

I wanted to access the Camunda CDI Beans BusinessProcess, ProcessVariables or CamundaTaskForm from my JSF forms as shown in the your example under http://docs.camunda.org/7.3/guides/getting-started-guides/java-ee/ or http://docs.camunda.org/7.3/real-life/how-to/#user-interface.
Are there any Spring Beans with similar functionality that I can access directly from my JSF forms using expression language? Or do I have to implement my own backing beans with Spring and call the corresponding Camunda functionality from my own beans?

Thanks and regards
Jakob

Ronny Bräunlich

unread,
Jun 2, 2015, 7:43:21 AM6/2/15
to camunda-...@googlegroups.com, jakob.s...@gmail.com
Hello Jakob,

yes, you will have to write some beans to call them with the expression language.
The engine-spring module contains some annotations, which are quite similar to the CDI ones and which may help you.
You can annotation your bean and make use of some injected values. An example can be found here.
Also, when you make the camunda services, like RuntimeService, available in your Spring context.xml you should be able to call the service methods directly via expression language expressions.

Cheers,
Ronny

jakob.s...@gmail.com

unread,
Jun 2, 2015, 7:58:40 AM6/2/15
to camunda-...@googlegroups.com, jakob.s...@gmail.com
Thanks, it's clear now!
Jakob

jakob.s...@gmail.com

unread,
Jun 17, 2015, 5:01:05 AM6/17/15
to camunda-...@googlegroups.com, jakob.s...@gmail.com
Ronny,

I tried to replace the CDI calls by calling the Spring Camunda API directly, but I have some troubles to implement similar behaviour...

My concrete questions:
1. How do I implement camundaTaskForm.startTaskForm()?
I tried with taskService.claim(taskId, userId) but I am not sure about how to get the correct taskId: do I have to loop through the child activity instances of my ProcessInstance, or is there an other, simpler way?

2. How can I access process variables from my JSF backing bean?
Of course I could use runtimeService.getVariables(executionId), but how do I get the current executionId of my ProcessInstance? With runtimeService.getActivityInstance(processId).getExecutionIds() I get an array of executionIds??

3. Is there a way to use the Camunda External Task Forms (http://docs.camunda.org/7.2/guides/user-guide/#task-forms) with Spring and JSF? Unfortunately the given example with JSF is a CDI example...

Thanks and regards
Jakob

Jaap Sperling

unread,
Jun 17, 2015, 5:33:59 AM6/17/15
to camunda-...@googlegroups.com, jakob.s...@gmail.com
Hi,

For 1:
The Task instance has a #getProcessInstanceId method, thereby giving you a handle on the task in the "owning" process instance.
However, having the taskId is enough to call TaskService#complete(taskId).

If the Task is associated with a Form, you call the FormService#submitTaskForm(taskId, mapWithKeyValuesFromForm)

HTH
Jaap

jakob.s...@gmail.com

unread,
Jun 18, 2015, 7:05:47 AM6/18/15
to camunda-...@googlegroups.com, jakob.s...@gmail.com
Thanks. However, I still do not understand how to use the FormService with Spring and JSF... :-(

Ronny Bräunlich

unread,
Jun 23, 2015, 2:10:23 AM6/23/15
to camunda-...@googlegroups.com, jakob.s...@gmail.com
Hallo Jakob,

excuse me for taking so long to answer.
Combining JSF and SpringBeans is not as easy as you'd hope it to be.
You can find some articles here [1] and here [2] and the Spring documentation contains a chapter about it, too [3], but that relates to JSF 1.2

Since you stated that you already have a Spring/JSF application, does the SpringBean access from JSF already work in your application?

Cheers,
Ronny

[1] http://www.beyondjava.net/blog/integrate-jsf-2-spring-3-nicely/
[2]http://www.mkyong.com/jsf2/jsf-2-0-spring-integration-example/
[3]http://docs.spring.io/spring/docs/4.2.0.RC1/spring-framework-reference/htmlsingle/#jsf
Reply all
Reply to author
Forward
0 new messages