I am implementing a Java ExternalTaskHandler, to handle a Camunda External Task. I am returning an array of objects as a result of the task. Unfortunately when I return this array, I get an error, that Camunda is not able to deserialize my object.
My code is the following:
public class MyClass implements ExternalTaskHandler
{
public void execute(ExternalTask externalTask, ExternalTaskService externalTaskService)
{
// Construct the returned object
List<MyObject> myObjects = new ArrayList<MyObject>();
myObjects.add(new MyObject());
// Put it in the response
Map<String,Object> returnedObjects = new HashMap<String,Object>();
returnedObjects.put("myObjects", myObjects);
// Finish the task -- this is where the error occurs
externalTaskService.setVariables(externalTask, returnedObjects);
}
}
The error is the following:
TASK/CLIENT-01009 Exception while completing the external task:
The corresponding process instance could not be resumed. Reason: status code: 500, reason phrase:
{"type":"ProcessEngineException","message":"Cannot deserialize object in variable 'returnedObjects': SPIN/JACKSON-JSON-01007 Cannot construct java type from string 'java.util.ArrayList<my.test.MyObject>'","code":0}
Interestingly, if I replace the list of MyObject with a List of String, let's say, then the code works.
What should I add or configure to allow Camunda to deserialize my object successfully?
EDIT: here is the implementation of MyObject
:
public class MyObject
{
private String name;
private List<String> values;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<String> getValues() {
return values;
}
public void setValues(List<String> values) {
this.values = values;
}
}
While making your object a Serializable may technically be the solution, you should not use Java serialization for process data.
In more recent Camunda 7 releases Java serialization has be deprecated. Reasons include the language dependence and tight coupling it creates. Different consumers of the process data need to have the Java class available. Every update to it requires updates to other services accessing the data. Versioning of Serializables is another challenge...
Anyway: You should serialize to JSON. This way any client (Java or not) will be able to work with the data, you can easily work with the data in a human readable format, can use different programming languages, can use jsonPath to navigate it in the process, have better interoperability with DMN/FEEL, can easily use it on the UI layer if needed,... and are better prepared - in Camunda 8 JSON is the only supported serialization and FEEL is the expression language (no more JUEL).
Here is an example: https://github.com/rob2universe/c7-rest-task-worker/blob/bff52eccfe569dcd25f39231906f9e209c5b4467/src/main/java/com/camunda/example/worker/RESTWorker.java#L33