Hello, I’m working on a POC deployment architecture for handling what will end up being lots of long running external tasks. My hope was to create a generic java service that I could configure to lock and complete various topics, solely for use with external tasks – my camunda process engine and executor are within a webapp tier elsewhere.
I am able to poll and lock the topics I’m interested in, however when I want to take any action on the task, complete, handleFailure, or unlock, I am met with this NPE parsing error:
12:21:03.545 [main] ERROR org.camunda.bpm.engine.context - ENGINE-16004 Exception while closing command context: ENGINE-01009 Error while parsing process
org.camunda.bpm.engine.ProcessEngineException: ENGINE-01009 Error while parsing process
at org.camunda.bpm.engine.impl.bpmn.parser.BpmnParseLogger.parsingProcessException(BpmnParseLogger.java:46) ~[camunda-engine-7.7.0.jar:7.7.0]
at org.camunda.bpm.engine.impl.bpmn.parser.BpmnParse.execute(BpmnParse.java:258) ~[camunda-engine-7.7.0.jar:7.7.0]
at org.camunda.bpm.engine.impl.bpmn.deployer.BpmnDeployer.transformDefinitions(BpmnDeployer.java:101) ~[camunda-engine-7.7.0.jar:7.7.0]
at org.camunda.bpm.engine.impl.AbstractDefinitionDeployer.transformResource(AbstractDefinitionDeployer.java:96) ~[camunda-engine-7.7.0.jar:7.7.0]
at org.camunda.bpm.engine.impl.AbstractDefinitionDeployer.parseDefinitionResources(AbstractDefinitionDeployer.java:71) ~[camunda-engine-7.7.0.jar:7.7.0]
at org.camunda.bpm.engine.impl.AbstractDefinitionDeployer.deploy(AbstractDefinitionDeployer.java:61) ~[camunda-engine-7.7.0.jar:7.7.0]
at org.camunda.bpm.engine.impl.persistence.deploy.cache.CacheDeployer$2.call(CacheDeployer.java:62) ~[camunda-engine-7.7.0.jar:7.7.0]
at org.camunda.bpm.engine.impl.persistence.deploy.cache.CacheDeployer$2.call(CacheDeployer.java:59) ~[camunda-engine-7.7.0.jar:7.7.0]
at org.camunda.bpm.engine.impl.interceptor.CommandContext.runWithoutAuthorization(CommandContext.java:473) ~[camunda-engine-7.7.0.jar:7.7.0]
at org.camunda.bpm.engine.impl.persistence.deploy.cache.CacheDeployer.deployOnlyGivenResourcesOfDeployment(CacheDeployer.java:59) ~[camunda-engine-7.7.0.jar:7.7.0]
at org.camunda.bpm.engine.impl.persistence.deploy.cache.ResourceDefinitionCache.resolveDefinition(ResourceDefinitionCache.java:109) ~[camunda-engine-7.7.0.jar:7.7.0]
at org.camunda.bpm.engine.impl.persistence.deploy.cache.ResourceDefinitionCache.findDeployedDefinitionById(ResourceDefinitionCache.java:52) ~[camunda-engine-7.7.0.jar:7.7.0]
at org.camunda.bpm.engine.impl.persistence.deploy.cache.DeploymentCache.findDeployedProcessDefinitionById(DeploymentCache.java:73) ~[camunda-engine-7.7.0.jar:7.7.0]
at org.camunda.bpm.engine.impl.persistence.entity.ExecutionEntity.ensureProcessDefinitionInitialized(ExecutionEntity.java:752) ~[camunda-engine-7.7.0.jar:7.7.0]
at org.camunda.bpm.engine.impl.persistence.entity.ExecutionEntity.getProcessDefinition(ExecutionEntity.java:734) ~[camunda-engine-7.7.0.jar:7.7.0]
at org.camunda.bpm.engine.impl.cfg.auth.AuthorizationCommandChecker.checkUpdateProcessInstance(AuthorizationCommandChecker.java:184) ~[camunda-engine-7.7.0.jar:7.7.0]
at org.camunda.bpm.engine.impl.cfg.auth.AuthorizationCommandChecker.checkUpdateProcessInstanceById(AuthorizationCommandChecker.java:178) ~[camunda-engine-7.7.0.jar:7.7.0]
at org.camunda.bpm.engine.impl.cmd.HandleExternalTaskCmd.execute(HandleExternalTaskCmd.java:55) ~[camunda-engine-7.7.0.jar:7.7.0]
at org.camunda.bpm.engine.impl.cmd.HandleExternalTaskCmd.execute(HandleExternalTaskCmd.java:30) ~[camunda-engine-7.7.0.jar:7.7.0]
at org.camunda.bpm.engine.impl.interceptor.CommandExecutorImpl.execute(CommandExecutorImpl.java:24) ~[camunda-engine-7.7.0.jar:7.7.0]
at org.camunda.bpm.engine.impl.interceptor.CommandContextInterceptor.execute(CommandContextInterceptor.java:104) ~[camunda-engine-7.7.0.jar:7.7.0]
at org.camunda.bpm.engine.impl.interceptor.ProcessApplicationContextInterceptor.execute(ProcessApplicationContextInterceptor.java:66) [camunda-engine-7.7.0.jar:7.7.0]
at org.camunda.bpm.engine.impl.interceptor.LogInterceptor.execute(LogInterceptor.java:30) [camunda-engine-7.7.0.jar:7.7.0]
at org.camunda.bpm.engine.impl.ExternalTaskServiceImpl.handleFailure(ExternalTaskServiceImpl.java:55) [camunda-engine-7.7.0.jar:7.7.0]
at org.camunda.bpm.engine.impl.ExternalTaskServiceImpl.handleFailure(ExternalTaskServiceImpl.java:51) [camunda-engine-7.7.0.jar:7.7.0]
at io.insurdata.workflow.ext.ExternalWorker.work(ExternalWorker.java:61) [classes/:na]
at io.insurdata.workflow.ext.ExternalWorkerMain.doMain(ExternalWorkerMain.java:39) [classes/:na]
at io.insurdata.workflow.ext.ExternalWorkerMain.main(ExternalWorkerMain.java:13) [classes/:na]
Caused by: java.lang.NullPointerException: null
at org.camunda.bpm.engine.impl.history.parser.HistoryParseListener.addActivityHandlers(HistoryParseListener.java:233) ~[camunda-engine-7.7.0.jar:7.7.0]
at org.camunda.bpm.engine.impl.history.parser.HistoryParseListener.parseStartEvent(HistoryParseListener.java:142) ~[camunda-engine-7.7.0.jar:7.7.0]
at org.camunda.bpm.engine.impl.bpmn.parser.BpmnParse.parseStartEvents(BpmnParse.java:858) ~[camunda-engine-7.7.0.jar:7.7.0]
at org.camunda.bpm.engine.impl.bpmn.parser.BpmnParse.parseScope(BpmnParse.java:636) ~[camunda-engine-7.7.0.jar:7.7.0]
at org.camunda.bpm.engine.impl.bpmn.parser.BpmnParse.parseProcess(BpmnParse.java:545) ~[camunda-engine-7.7.0.jar:7.7.0]
at org.camunda.bpm.engine.impl.bpmn.parser.BpmnParse.parseProcessDefinitions(BpmnParse.java:479) ~[camunda-engine-7.7.0.jar:7.7.0]
at org.camunda.bpm.engine.impl.bpmn.parser.BpmnParse.parseRootElement(BpmnParse.java:283) ~[camunda-engine-7.7.0.jar:7.7.0]
at org.camunda.bpm.engine.impl.bpmn.parser.BpmnParse.execute(BpmnParse.java:248) ~[camunda-engine-7.7.0.jar:7.7.0]
... 26 common frames omitted
It’s just a guess, but I’m wondering if this has to do with my instantiating a full ProcessEngine and then getting the ExternalTaskService from it…it looks like the error is resulting from trying to parse a bpmn process file that will not exist on this server (it’s in a war on the webapp). Is there a way for me overcome this without the need for parsing and just have essentially a standalone ExternalTaskService, e.g. get task, complete task, report task ? Below is, simplistically, all that the executable does:
public static void doMain() throws Exception {
ProcessEngine processEngine = ProcessEngineConfiguration.createStandaloneProcessEngineConfiguration()
.setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_FALSE)
.setJdbcDriver(config.getJdbcDriver())
.setJdbcUrl(config.getJdbcUrl())
.setJdbcUsername(config.getJdbcUser())
.setJdbcPassword(config.getJdbcPassword())
.setHistory("auto")
.setJobExecutorActivate(false)
.buildProcessEngine();
ExternalTaskService externalTaskService = processEngine.getExternalTaskService();
logger.info("Building external task query...");
ExternalTaskQueryBuilder builder = externalTaskService.fetchAndLock(1, workerId);
for (String topic : config.getTopics()) {
logger.info("Subscribing to external task topic {} at lock interval {}", topic, lockInterval);
builder.topic(topic, lockInterval);
}
while (true) {
List<LockedExternalTask> tasks = builder.execute();
for (LockedExternalTask task : tasks) {
if (logger.isDebugEnabled()) {
logger.debug("Got topic {}, task {}", task.getTopicName(), task.getId());
}
try {
// Do work on task...
externalTaskService.complete(task.getId(), workerId); // Error is thrown HERE
} catch (Exception e) {
logger.error("Failed to complete task {}", task.getId(), e);
externalTaskService.handleFailure(task.getId(), workerId, e.getMessage(), 0, lockInterval); // Or thrown HERE
}
}
Thread.sleep(config.getPollInterval());
}
}