How to use the DMN-Engine?

880 views
Skip to first unread message

Frank Langelage

unread,
Sep 24, 2015, 2:43:09 AM9/24/15
to camunda BPM users
Hey guys,

I tried to use a DMN file (assign-approver-groups.dmn) with latest Camunda 7.4.0-SNAPSHOT.
Using WildFly and this piece of code.
Deployment works fine, but when calling it like this (copied from [1]):
    private static void executeDecisionTable( final InputStream decisionTable )
    {
        DmnEngine engine = new DmnEngineConfigurationImpl().buildEngine();
        DmnDecision decision = engine.parseDecision( decisionTable );

        Map<String, Object> data = new HashMap<>();
        data.put( "amount", Integer.valueOf( 4711 ) );
        data.put( "invoiceCategory", "Spesen" );

        DmnDecisionResult result = engine.evaluate( decision, data );
    }

I get this exception cause:
Caused by: org.camunda.bpm.dmn.engine.DmnExpressionException: DMN-01015 Unable to find script engine for expression language 'null'.
    at org.camunda.bpm.dmn.engine.impl.DmnEngineLogger.noScriptEngineFoundForLanguage(DmnEngineLogger.java:81)
    at org.camunda.bpm.dmn.engine.impl.context.DmnDecisionContextImpl.getScriptEngineForNameChecked(DmnDecisionContextImpl.java:303)
    at org.camunda.bpm.dmn.engine.impl.context.DmnDecisionContextImpl.evaluateExpression(DmnDecisionContextImpl.java:283)
    at org.camunda.bpm.dmn.engine.impl.context.DmnDecisionContextImpl.evaluateExpression(DmnDecisionContextImpl.java:266)
    at org.camunda.bpm.dmn.engine.impl.context.DmnDecisionContextImpl.evaluateInputClause(DmnDecisionContextImpl.java:186)
    at org.camunda.bpm.dmn.engine.impl.context.DmnDecisionContextImpl.evaluateDecisionTableInputs(DmnDecisionContextImpl.java:175)
    at org.camunda.bpm.dmn.engine.impl.context.DmnDecisionContextImpl.evaluateDecisionTable(DmnDecisionContextImpl.java:118)
    at org.camunda.bpm.dmn.engine.impl.context.DmnDecisionContextImpl.evaluateDecision(DmnDecisionContextImpl.java:104)
    at org.camunda.bpm.dmn.engine.impl.DmnEngineImpl.evaluate(DmnEngineImpl.java:136)
    at biz.mbisoftware.fn.ejb.session.camunda.CamundaInterface.executeDecisionTable(CamundaInterface.java:398)

What do I have too add or define else?

[1] https://github.com/camunda/camunda-engine-dmn/blob/master/README.md

Regards, Frank

Sebastian Menski

unread,
Sep 24, 2015, 3:35:19 AM9/24/15
to camunda BPM users
Hi Frank,

sorry for this useless exception message. I just pushed an improvement for it [1]. It seems that your project has no dependency
to a JUEL script engine like the camunda-scriptengine-juel or the one embedded in the camunda-engine.

In which context do you execute your code? A standalone java application or a process application or something else? 

Cheers,
Sebastian

Frank Langelage

unread,
Sep 24, 2015, 5:57:13 AM9/24/15
to camunda BPM users
Sebastian,

thank's for the quick response.

It's using a process application, deployment method I used for the dmn-file is the same as for a bpmn-file.
        DeploymentBuilder deploymentBuilder = this.repositoryService.createDeployment();
        deploymentBuilder
.enableDuplicateFiltering( true );
        deploymentBuilder
.addInputStream( fileName, new ByteArrayInputStream( fileContent ) );
        deploymentBuilder
.name( fileName );
       
Deployment deployment = deploymentBuilder.deploy();
       
String processApplication = this.managementService.getProcessApplicationForDeployment( deployment.getId() );
       
if ( processApplication == null ) {
           
this.managementService.registerProcessApplication( deployment.getId(), this.camundaProcessApplication.getReference() );
       
}

And bpmn is working fine calling the delegates or using CDI.

Possibly because I create a new DmnEngine in my application like shown in my OP, this engine is not aware of the juel engine embedded in camunda-engine module as the camunda-engine-dmn module has no dependency defined in module.xml to it. Only the other way around.
Can I get an instance of a DmnEngine from the camunda-engine module instead of creating it like I did?

Sebastian Menski

unread,
Sep 24, 2015, 7:26:05 AM9/24/15
to camunda BPM users
Hi Frank,

you can get the DMN engine from the process engine configuration:

DmnEngine dmnEngine = processEngineConfiguration.getDmnEngine();

Does this help you?

Cheers,
Sebastian

Frank Langelage

unread,
Sep 24, 2015, 5:50:38 PM9/24/15
to camunda BPM users
One step further, but not yet at the end:

Now my code looks like this:
        ProcessEngineImpl processEngine = (ProcessEngineImpl)BpmPlatform.getDefaultProcessEngine();
        ProcessEngineConfigurationImpl processEngineConfiguration = processEngine.getProcessEngineConfiguration();
        DmnEngine engine = processEngineConfiguration.getDmnEngine();

        DmnDecision decision = engine.parseDecision( decisionTable );

which gives me
Caused by: java.lang.NullPointerException
    at org.camunda.bpm.engine.impl.scripting.engine.ScriptingEngines.getScriptEngineForLanguage(ScriptingEngines.java:102)
    at org.camunda.bpm.dmn.engine.impl.context.DmnDecisionContextImpl.getScriptEngineForName(DmnDecisionContextImpl.java:311)
    at org.camunda.bpm.dmn.engine.impl.context.DmnDecisionContextImpl.getScriptEngineForNameChecked(DmnDecisionContextImpl.java:298)

    at org.camunda.bpm.dmn.engine.impl.context.DmnDecisionContextImpl.evaluateExpression(DmnDecisionContextImpl.java:283)
    at org.camunda.bpm.dmn.engine.impl.context.DmnDecisionContextImpl.evaluateExpression(DmnDecisionContextImpl.java:266)
    at org.camunda.bpm.dmn.engine.impl.context.DmnDecisionContextImpl.evaluateInputClause(DmnDecisionContextImpl.java:186)
    at org.camunda.bpm.dmn.engine.impl.context.DmnDecisionContextImpl.evaluateDecisionTableInputs(DmnDecisionContextImpl.java:175)
    at org.camunda.bpm.dmn.engine.impl.context.DmnDecisionContextImpl.evaluateDecisionTable(DmnDecisionContextImpl.java:118)
    at org.camunda.bpm.dmn.engine.impl.context.DmnDecisionContextImpl.evaluateDecision(DmnDecisionContextImpl.java:104)
    at org.camunda.bpm.dmn.engine.impl.DmnEngineImpl.evaluate(DmnEngineImpl.java:136)
    at biz.mbisoftware.fn.ejb.session.camunda.CamundaInterface.executeDecisionTable(CamundaInterface.java:378)

Sebastian Menski

unread,
Sep 25, 2015, 3:33:22 AM9/25/15
to camunda BPM users
Hi Frank,

I'm sorry it seems you found a bug which was introduced with a fix around script engine caching [1]. I created a ticket [2]. So thanks for reporting this issue.

Cheers,
Sebastian


Frank Langelage

unread,
Sep 25, 2015, 9:44:36 AM9/25/15
to camunda BPM users
Hi Sebastian,

I switched back to

        DmnEngine engine = new DmnEngineConfigurationImpl().buildEngine();
and added camunda-scriptengine-juel, juel-api. juel-spi and juel-impl to my ear's lib folder.
Now decision tables can be processed successfully.

Cheers, Frank

Philipp Ossler

unread,
Oct 16, 2015, 8:59:11 AM10/16/15
to camunda BPM users
Hi Frank,

have a look at the new DecisionService [1] that allows you to evaluate decisions. See https://app.camunda.com/jira/browse/CAM-4338

Greetings,
Philipp

Frank Langelage

unread,
Oct 25, 2015, 8:21:37 AM10/25/15
to camunda BPM users
Hi Phillip,

thanks for your update.
I only now had the time for further testing the DMN integration.
I tried to inject the Decision service like the other already used services, but this did not work because of missing Producer. Created a PR to add them. See [1].
Okay, used ProcessEngines.getDefaultProcessEngine().getDecisionService() for the moment.
But then I got this Exception:
Caused by: java.lang.IncompatibleClassChangeError: Class org.camunda.bpm.dmn.feel.impl.FeelEngineProviderImpl does not implement the requested interface org.camunda.bpm.dmn.feel.FeelEngineProvider
    at org
.camunda.bpm.dmn.engine.impl.context.DmnContextFactoryImpl.createDecisionContext(DmnContextFactoryImpl.java:26)
    at org
.camunda.bpm.dmn.engine.impl.DmnEngineImpl.evaluate(DmnEngineImpl.java:135)
    at org
.camunda.bpm.engine.impl.dmn.cmd.EvaluateDecisionByKeyCmd.execute(EvaluateDecisionByKeyCmd.java:66)
    at org
.camunda.bpm.engine.impl.dmn.cmd.EvaluateDecisionByKeyCmd.execute(EvaluateDecisionByKeyCmd.java:36)
    at org
.camunda.bpm.engine.impl.interceptor.CommandExecutorImpl.execute(CommandExecutorImpl.java:24)
    at org
.camunda.bpm.engine.impl.interceptor.CommandContextInterceptor.execute(CommandContextInterceptor.java:97)
    at org
.camunda.bpm.engine.impl.interceptor.JtaTransactionInterceptor.execute(JtaTransactionInterceptor.java:59)
    at org
.camunda.bpm.engine.impl.interceptor.LogInterceptor.execute(LogInterceptor.java:32)
    at org
.camunda.bpm.engine.impl.DecisionServiceImpl.evaluateDecisionByKey(DecisionServiceImpl.java:35)


This is caused because the interface class org.camunda.bpm.dmn.feel.FeelEngineProvider exists in 2 modules, camunda-engine-feel-api and camunda-engine-feel-juel.
This problem might be WildFly related. For me there are 2 options to solve this:
- remove the module camunda-engine-feel-api
- don't include the API classes in camunda-engine-feel-juel. I think is the better solution. Therefore [2].

Regards, Frank

[1]: https://github.com/camunda/camunda-bpm-platform/pull/184
[2]: https://github.com/camunda/camunda-engine-dmn/pull/3

Philipp Ossler

unread,
Oct 26, 2015, 5:41:26 AM10/26/15
to camunda BPM users
Hi Frank,

thank you for your feedback. I created two issues [1] and [2]. I will look at it soon and give feedback to you.

Greetings,
Philipp

Philipp Ossler

unread,
Oct 27, 2015, 3:00:53 AM10/27/15
to camunda BPM users
Hi Frank,

I merged [1] and found another solution for [2]. So both problems are fixed now.

Greetings,
Philipp
Reply all
Reply to author
Forward
0 new messages