camunda / camunda-bpm-platform

Flexible framework for workflow and decision automation with BPMN and DMN. Integration with Quarkus, Spring, Spring Boot, CDI.
https://camunda.com/
Apache License 2.0
4.03k stars 1.53k forks source link

Model API cannot set values to null #2126

Open ThorbenLindhauer opened 9 years ago

ThorbenLindhauer commented 9 years ago

This issue was imported from JIRA:

Field Value
JIRA Link CAM-4178
Reporter rP62zaw
What is this name? This pseudonym name was generated based on the user name in JIRA to protect the personal data of our JIRA users. You can use this identifier to search for issues by the same reporter.
Has restricted visibility comments false

See the test case below. It fails with this exception:

org.camunda.bpm.engine.ProcessEngineException: Delegate expression  did neither resolve to an implementation of interface org.camunda.bpm.engine.impl.pvm.delegate.ActivityBehavior nor interface org.camunda.bpm.engine.delegate.JavaDelegate
    at org.camunda.bpm.engine.impl.bpmn.behavior.ServiceTaskDelegateExpressionActivityBehavi

As you can see a "ServiceTaskDelegateExpressionActivityBehavior" was choosen - even if I set

    serviceTask.setCamundaDelegateExpression(null);

I digged a bit into it and found that this results in havind the

   delegateExpression=""

Hence an empty string instead of null.

Not sure if this is a bug in the ModelAPI or if it should better be checked for emptry string in https://github.com/camunda/camunda-bpm-platform/blob/master/engine/src/main/java/org/camunda/bpm/engine/impl/bpmn/parser/BpmnParse.java#L1697 as done with expressions as well. https://github.com/camunda/camunda-bpm-platform/blob/master/engine/src/main/java/org/camunda/bpm/engine/impl/bpmn/parser/BpmnParse.java#L1703

 @Test
  public void testModelApiBug() {
    BpmnModelInstance modelInstance = Bpmn.createEmptyModel();
    Definitions definitions = modelInstance.newInstance(Definitions.class);
    definitions.setTargetNamespace("http://camunda.org/examples");
    modelInstance.setDefinitions(definitions);
    org.camunda.bpm.model.bpmn.instance.Process process = modelInstance.newInstance(org.camunda.bpm.model.bpmn.instance.Process.class);
    process.setId("test");
    definitions.addChildElement(process);

    StartEvent startEvent = modelInstance.newInstance(StartEvent.class);
    startEvent.setAttributeValue("id", "startEvent1", true);   
    process.addChildElement(startEvent);

    ServiceTask serviceTask = modelInstance.newInstance(ServiceTask.class);
    serviceTask.setAttributeValue("id", "serviceTask1", true);   
    serviceTask.setCamundaClass(null);
    serviceTask.setCamundaDelegateExpression(null);
    serviceTask.setCamundaExpression("#{true}"); // Noop
    process.addChildElement(serviceTask);

    createSequenceFlow(process, startEvent, serviceTask);

    repositoryService().createDeployment().addModelInstance("test.bpmn", modelInstance).deploy();
    runtimeService().startProcessInstanceByKey("test");
  }

  public SequenceFlow createSequenceFlow(org.camunda.bpm.model.bpmn.instance.Process process, FlowNode from, FlowNode to) {
    String identifier = from.getId() <ins> "-" </ins> to.getId();
    SequenceFlow sequenceFlow = createElement(process, identifier, SequenceFlow.class);
    process.addChildElement(sequenceFlow);
    sequenceFlow.setSource(from);
    from.getOutgoing().add(sequenceFlow);
    sequenceFlow.setTarget(to);
    to.getIncoming().add(sequenceFlow);
    return sequenceFlow;
  }
  protected <T extends BpmnModelElementInstance> T createElement(BpmnModelElementInstance parentElement, String id, Class<T> elementClass) {
    T element = parentElement.getModelInstance().newInstance(elementClass);
    element.setAttributeValue("id", id, true);
    parentElement.addChildElement(element);
    return element;
  }

Links:

ThorbenLindhauer commented 8 years ago

This comment was imported from JIRA and written by user zZ6Eda

What is this name? This pseudonym name was generated based on the user name in JIRA to protect the personal data of our JIRA users. You can use this identifier to search for issues by the same reporter.


Is this a valid workaround?

serviceTask.removeAttributeNs(org.camunda.bpm.model.bpmn.impl.BpmnModelConstants.CAMUNDA_NS, "delegateExpression")

ThorbenLindhauer commented 6 years ago

This comment was imported from JIRA and written by user @nevries


This clearly also happens on

UserTask.setCamundaAssignee(null);
UserTask.setCamundaCandidateGroups(null);
...

Hence, setting assignee to null yields in a user task that is always assigned to a user with name empty string. Unpleasent behaviour...