Field Injection support on Bpmn builder via code

Hi All,

We generate our BPMN definitions using the java api Bpmn.createExecutableProcess(). I would like to leverage the field injection ability on service task delegates. However, the builder API doesn’t expose the required methods to define this programmatically.

Any tips or suggestions on how to get around this?

Thanks in advance.

Hi @Ujwal,

after generating the model with the fluent api, you can read it (https://docs.camunda.org/manual/latest/user-guide/model-api/bpmn-model-api/read-a-model/), navigate to your service tasks and set the attributes.

Basic examples are included in the page I linked (and I think you already read).

Hope this helps, Ingo

Hi @Ingo_Richtsmeier

Thanks for the prompt response, apologies for getting back with a delay.

I have tried as per your suggestion in the below code.

final BpmnModelInstance modelInstance = Bpmn.createExecutableProcess(“testProcess”).startEvent().serviceTask(“task”).camundaClass(“com.example.Test”).endEvent().done();
final ModelElementInstance modelElement = modelInstance.getModelElementById(“task”);
final CamundaField field = modelElement.getModelInstance().newInstance(CamundaField.class);
field.setCamundaName(“injection”);
field.setCamundaExpression(“${myBean}”);
modelElement.addChildElement(field);
Bpmn.validateModel(modelInstance);

and I get the following error

Exception in thread “main” org.camunda.bpm.model.xml.ModelException: New child is not a valid child element type: field; valid types are: [documentation, extensionElements, auditing, monitoring, categoryValueRef, incoming, outgoing, ioSpecification, property, dataInputAssociation, dataOutputAssociation, resourceRole, loopCharacteristics]
at org.camunda.bpm.model.xml.impl.util.ModelUtil.getIndexOfElementType(ModelUtil.java:203)
at org.camunda.bpm.model.xml.impl.instance.ModelElementInstanceImpl.findElementToInsertAfter(ModelElementInstanceImpl.java:328)
at org.camunda.bpm.model.xml.impl.instance.ModelElementInstanceImpl.addChildElement(ModelElementInstanceImpl.java:288)

For the time being, I checked out the bpmn-model-api module from github and added the below two methods to the ServiceTaskBuilder.java

public ServiceTaskBuilder camundaField(String fieldName, String fieldValue) {
final CamundaField field = createInstance(CamundaField.class);
field.setCamundaName(fieldName);
field.setCamundaStringValue(fieldValue);
addExtensionElement(field);
return myself;
}

public ServiceTaskBuilder camundaExpressionField(String fieldName, String expression) {
final CamundaField field = createInstance(CamundaField.class);
field.setCamundaName(fieldName);
field.setCamundaExpression(expression);
addExtensionElement(field);
return myself;
}

With the above change to ServiceTaskBuilder I was able to achieve the desired outcome. Please let me know if I am missing something from your suggestion or if field injections are not coded into the builders yet.

Hi @Ujwal,

you’re missing a nesting with the extension element:

This will do the trick:

    final BpmnModelInstance modelInstance = Bpmn.createExecutableProcess("testProcess").startEvent().serviceTask("task").camundaClass("com.example.Test").endEvent().done();
    final ModelElementInstance taskElement = modelInstance.getModelElementById("task");
    
    ExtensionElements extension = taskElement.getModelInstance().newInstance(ExtensionElements.class);
    taskElement.addChildElement(extension);
    
    CamundaField camundaField = extension.getModelInstance().newInstance(CamundaField.class);
    camundaField.setCamundaName("injection");
    camundaField.setCamundaExpression("${myBean}");
    extension.addChildElement(camundaField);
    Bpmn.validateModel(modelInstance);

Hope this helps, Ingo