Call a Camel Route from the Process Instance

Hello,

I have a problem when use ${camel.sendTo(‘direct:asyncService’)} in my BPM flow. When testing the system, I found out the service task gets a Error while evaluating expression: ${camel.sendTo(‘direct:asyncService’)}. Cause: Could not lookup beanmanager in jndi.

I am working with spring in my context I define this:

<!-- bind the process engine service as Spring Bean -->
<bean name="processEngineService" class="org.camunda.bpm.BpmPlatform"
	factory-method="getProcessEngineService" />

<!-- bind the default process engine as Spring Bean -->
<bean name="processEngine" factory-bean="processEngineService"
	factory-method="getDefaultProcessEngine" />

<bean id="repositoryService" factory-bean="processEngine"
	factory-method="getRepositoryService" />
<bean id="runtimeService" factory-bean="processEngine"
	factory-method="getRuntimeService" />
<bean id="taskService" factory-bean="processEngine"
	factory-method="getTaskService" />
<bean id="historyService" factory-bean="processEngine"
	factory-method="getHistoryService" />
<bean id="managementService" factory-bean="processEngine"
	factory-method="getManagementService" />
<bean id="camel" class="org.camunda.bpm.camel.spring.CamelServiceImpl">
	<property name="processEngine" ref="processEngine" />
	<property name="camelContext" ref="camelContext" />
</bean>

<bean id="camel" class="org.camunda.bpm.camel.spring.CamelServiceImpl">
	<property name="processEngine" ref="processEngine" />
	<property name="camelContext" ref="camelContext" />
</bean>

My bpmn file has the following:

  <bpmn:serviceTask id="Task_187w3iw" name="Send" camunda:expression="${camel.sendTo(&#39;direct:asyncService&#39;)}">
    <bpmn:incoming>SequenceFlow_1m7wu3i</bpmn:incoming>
    <bpmn:outgoing>SequenceFlow_0sw3wk8</bpmn:outgoing>
  </bpmn:serviceTask>

My CamelBootStrap has the following:

public class CamelBootStrap {
private final static Logger log =   Logger.getLogger(
       CamelBootStrap.class.getCanonicalName());

@Inject
private CamelContext camelContext;

@Inject
private ProcessEngine processEngine;

@Inject
private MessageRouteImpl messageRoute;

@PostConstruct
public void init() throws Exception {
	log.info("=======================");
	log.info("Initializing Camel");

	CamundaBpmComponent component = new CamundaBpmComponent(processEngine);
	component.setCamelContext(camelContext);
	
	camelContext.addComponent("camunda-bpm", component);
	camelContext.addRoutes(messageRoute);
	camelContext.start();
	

	log.info("Successfully started Camel with components: " + camelContext.getComponentNames());
	log.info("=======================");
}

@PreDestroy
public void shutDown() throws Exception {
	log.info("=======================");
	log.info("Shutting down Camel");
	camelContext.stop();
	log.info("=======================");
}

}

If you’re using WildFly/JBoss, might want to look at the Camel add-on.
I’ve had some good success adding it to my WildFly server with Camunda running in “shared” mode.

I’m using archetype: camunda-archetype-ejb-war-7.5.0 (preferring the CDI pattern - noting @Inject syntax in your code)

Here’s the Wildfly Compatibility matrix to help identify correct Camel version per app’ server.

In looking at your code, I’m not sure you want to directly call the camelContext start and stop. I like running Camel as an extension (noted above). Better support for async so that both Camunda and Camel can reasonably run without interfering with each other’s resource needs (i.e. non-blocking, etc.). This means that the Camel infrastructure starts up along with the server itself. And, Camel remains running (includes your context).

I also use JMS to support async requirements. But, SEDA also works - however SEDA doesn’t preserve your events when the server cycles. Camel also insists on clearing the SEDA in-memory “queue” prior to server shutdown (you’ll get a countdown timer on shutdown). This can be a minor annoyance if you’re in a dev/test cycle requiring server restarts.

Again noting your use of camelContext “start” and “stop”: The camel context, camel-routes included, should remain active. Shutting down the camel context would be like manually stopping your Camunda process. Better to just let it end per route definition (note: unless you’re testing).

I wrote an article on the topic:
Straight Through Process with Camunda BPM and Apache Camel

Includes source:
gs_codesamples/bpmcamundacamel2/

Here’s a Java snippet demonstrating a call into the camelcontext - though it’s interacting with an active route (i.e. not starting a new route) the syntax is similar:

NOTE: This code is called via a BPMN “send-message” implementation.

#{stpProcessDemo.returnProcessVariables2(execution)}
Map<String, Object> camelHeaderMap = new HashMap<>();
camelHeaderMap.put("JMSCorrelationID", jMSCorrelationID.toString());

String camelUri = "jmsBpm:queue:" + jMSReplyToName.toString();

ProducerTemplate producer = camelContext.createProducerTemplate();

LOGGER.info("*** returnProcessVariables sending to Camel URI: " + camelUri);
LOGGER.info("*** returnProcessVariables jsonResults: " + jsonResults);
producer.sendBodyAndHeaders(camelUri, jsonResults, camelHeaderMap);
1 Like

Thank you Garysamuelson, I have solved it. I had to delete the following dependency of my pom.xml

<dependency>
   <groupId>org.apache.camel</groupId>
   <artifactId>camel-cdi</artifactId>
   <version>${camel.version}</version>
</dependency>