Start process through REST API with variable in Json Object


#1

Hello,

I’m trying to start a very simple camunda process with one service activity but that service activity is supposed to use a variable which is a structured object.

I wrote my code to expect my variable to be of type com.fasterxml.jackson.databind.node.ArrayNode.

ArrayNode hddVariable = (ArrayNode) execution.getVariable(Variable.HDD.getKey());

I would like to start my process instance with the Camunda REST API using jersey-client but I haven’t been able to have camunda unserialize my json array into an ArrayNode.

The variable I send is something like that :

"hdd" : { "type" : "Object", "value" : "[{\"mntpoint\":\"pv.01\",\"size\":1,\"ondisk\":\"sda\",\"grow\":true,\"volgroup\":{\"name\":\"rootvg\",\"logvols\":[{\"name\":\"rootlv\",\"mntpoint\":\"/\",\"fstype\":\"ext4\",\"size\":4608},{\"name\":\"homelv\",\"mntpoint\":\"/home\",\"fstype\":\"ext4\",\"size\":128},{\"name\":\"nrblv\",\"mntpoint\":\"/nrb\",\"fstype\":\"ext4\",\"size\":256},{\"name\":\"optlv\",\"mntpoint\":\"/opt\",\"fstype\":\"ext4\",\"size\":2048},{\"name\":\"softlv\",\"mntpoint\":\"/software\",\"fstype\":\"ext4\",\"size\":3072},{\"name\":\"tmplv\",\"mntpoint\":\"/tmp\",\"fstype\":\"ext4\",\"size\":1024},{\"name\":\"varlv\",\"mntpoint\":\"/var\",\"fstype\":\"ext4\",\"size\":2048},{\"name\":\"varloglv\",\"mntpoint\":\"/var/log\",\"fstype\":\"ext4\",\"size\":1024},{\"name\":\"varlogaudlv\",\"mntpoint\":\"/var/log/audit\",\"fstype\":\"ext4\",\"size\":4096},{\"name\":\"swaplv\",\"mntpoint\":\"swap\",\"fstype\":\"swap\",\"size\":8192}]} } ]", "valueInfo" : { "objectTypeName" : "com.fasterxml.jackson.databind.node.ArrayNode", "serializationDataFormat" : "JSON" } }

But I have :
Deserialization Error: Cannot deserialize object in variable 'hdd': SPIN-PLUGIN-01002 Fallback serializer cannot handle deserialized objects

How could I use ArrayNode in variables ?


#2

Hi @Eric_Cornely,

I think serializationDataFormat mus be application/json.

Cheers,
Thorben


#3

Whatever JSON or application/json. I have an exception while getting the variable content :

An error occured while generating kickstart files: org.camunda.bpm.engine.ProcessEngineException: Cannot deserialize object in variable 'hdd': SPIN/JACKSON-JSON-01006 Cannot deserialize '[{"mntpoin...' to java type '[simple type, class com.fasterxml.jackson.databind.node.ArrayNode]' at org.camunda.bpm.engine.impl.variable.serializer.AbstractSerializableValueSerializer.readValue(AbstractSerializableValueSerializer.java:81) at org.camunda.bpm.engine.impl.variable.serializer.AbstractSerializableValueSerializer.readValue(AbstractSerializableValueSerializer.java:27) at org.camunda.bpm.engine.impl.persistence.entity.util.TypedValueField.getTypedValue(TypedValueField.java:93) at org.camunda.bpm.engine.impl.persistence.entity.VariableInstanceEntity.getTypedValue(VariableInstanceEntity.java:258) at org.camunda.bpm.engine.impl.core.variable.scope.AbstractVariableScope.getValueFromVariableInstance(AbstractVariableScope.java:127) at org.camunda.bpm.engine.impl.core.variable.scope.AbstractVariableScope.getVariable(AbstractVariableScope.java:114) at org.camunda.bpm.engine.impl.core.variable.scope.AbstractVariableScope.getVariable(AbstractVariableScope.java:110) at be.nrb.o2.bpmn.ksgen.GenerateKickstart.buildKsgenMessage(GenerateKickstart.java:125) at be.nrb.o2.bpmn.ksgen.GenerateKickstart.execute(GenerateKickstart.java:47)


#4

Please post the entire stack trace. This exception should have a root cause exception that provides more information.

Thanks,
Thorben


#5

@thorben, the full stacktrace is available on pastebin : http://pastebin.com/f7PV46C1


#6

Which Camunda version do you use?


#7

@thorben, we use 7.5.6-ee.


#8

Hi @Eric_Cornely,

I think the problem is that in JSON that you posted “value” key inside “hdd” object has String value, not an array value. Please take a look here for array examples in JSON http://www.w3schools.com/js/js_json_intro.asp

Cheers,
Askar


#9

Hi @aakhmerov,

The reason why I submit the array as a String is because when I submit it as an array :

"hdd" : { "type" : "Object", "value" : [ { "mntpoint" : "pv.01", "size" : 1, "ondisk" : "sda", "grow" : true, "volgroup" : { "name" : "rootvg", "logvols" : [ { "name" : "rootlv", "mntpoint" : "/", "fstype" : "ext4", "size" : 4608 }, { "name" : "homelv", "mntpoint" : "/home", "fstype" : "ext4", "size" : 128 }, { "name" : "nrblv", "mntpoint" : "/nrb", "fstype" : "ext4", "size" : 256 }, { "name" : "optlv", "mntpoint" : "/opt", "fstype" : "ext4", "size" : 2048 }, { "name" : "softlv", "mntpoint" : "/software", "fstype" : "ext4", "size" : 3072 }, { "name" : "tmplv", "mntpoint" : "/tmp", "fstype" : "ext4", "size" : 1024 }, { "name" : "varlv", "mntpoint" : "/var", "fstype" : "ext4", "size" : 2048 }, { "name" : "varloglv", "mntpoint" : "/var/log", "fstype" : "ext4", "size" : 1024 }, { "name" : "varlogaudlv", "mntpoint" : "/var/log/audit", "fstype" : "ext4", "size" : 4096 }, { "name" : "swaplv", "mntpoint" : "swap", "fstype" : "swap", "size" : 8192 } ] } } ], "valueInfo" : { "objectTypeName" : "com.fasterxml.jackson.databind.node.ArrayNode", "serializationDataFormat" : "application/json" } }

The exception tells me to send a String value:
org.camunda.bpm.engine.rest.exception.InvalidRequestException: Must provide 'null' or String value for value of SerializableValue type 'Object'.
See the full stacktrace on pastbin

Kr,

Eric


#10

Using it with a String is the correct way. I tried this code in a unit test and it works fine:

String serializedValue = "the long json String";
ObjectMapper objectMapper = new ObjectMapper();
ArrayNode arrayNode = objectMapper.readValue(serializedValue, javaType);

Could you

a) Provide simplified process application sources and exact steps to reproduce the problem?
or b) debug this and set a break point at JacksonJsonDataFormatMapper#mapInternalToJava and check what the parameters are (i.e. what is the JSON value), and if the classloader of ObjectMapper and ArrayNode are the same?

Cheers,
Thorben


#11

Hey @Eric_Cornely,

could you post your serialization and deserialization code here please. I think org.camunda.bpm.engine.rest.exception.InvalidRequestException: Must provide 'null' or String value for value of SerializableValue type 'Object'. refers not to field value, but to the whole object.

Cheers,
Askar.


#12

Ok I have setup a small project on github: https://github.com/ecornely/camunda-json

I have one single EJB that is supposed to log the content of a variable named “demo”.

In my code I expect that variable to be an ArrayNode so cast it directly but I never could start the process instance with a json array.

The class be.ecornely.StartProcess is a main that uses jersey-client to submit a new process instance.

Kr,

Eric


#13

Hi @Eric_Cornely,

yould you try with following patch? adjust_serialization.txt (1.6 KB)

Cheers,
Askar


#14

It fails on the putPOJO:

Exception in thread "main" com.fasterxml.jackson.databind.JsonMappingException: No serializer found for class org.camunda.bpm.engine.impl.util.json.JSONArray and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:275) at com.fasterxml.jackson.databind.SerializerProvider.mappingException(SerializerProvider.java:1109) at com.fasterxml.jackson.databind.SerializerProvider.reportMappingProblem(SerializerProvider.java:1134) at com.fasterxml.jackson.databind.ser.impl.UnknownSerializer.failForEmpty(UnknownSerializer.java:69) at com.fasterxml.jackson.databind.ser.impl.UnknownSerializer.serialize(UnknownSerializer.java:32) at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:292) at com.fasterxml.jackson.databind.ObjectMapper.writeValue(ObjectMapper.java:2484) at com.fasterxml.jackson.core.base.GeneratorBase.writeObject(GeneratorBase.java:367) at com.fasterxml.jackson.databind.node.POJONode.serialize(POJONode.java:112) at com.fasterxml.jackson.databind.node.ObjectNode.serialize(ObjectNode.java:304) at com.fasterxml.jackson.databind.node.ObjectNode.serialize(ObjectNode.java:304) at com.fasterxml.jackson.databind.node.ObjectNode.serialize(ObjectNode.java:304) at com.fasterxml.jackson.databind.ser.std.SerializableSerializer.serialize(SerializableSerializer.java:49) at com.fasterxml.jackson.databind.ser.std.SerializableSerializer.serialize(SerializableSerializer.java:27) at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:292) at com.fasterxml.jackson.databind.ObjectWriter$Prefetch.serialize(ObjectWriter.java:1419) at com.fasterxml.jackson.databind.ObjectWriter._configAndWriteValue(ObjectWriter.java:1147) at com.fasterxml.jackson.databind.ObjectWriter.writeValueAsString(ObjectWriter.java:1020) at be.ecornely.StartProcess.main(StartProcess.java:34)


#16

@Eric_Cornely, did it work after merge of PR?

Askar.


#17

@aakhmerov, no, still the same exception. I was looking into the code on camunda’s github to find where it fails and I’m sure it has to be passes as a String.

Jackson will be used to read it as a tree then it is supposed to be mapped to the destination type… the problem is somehow because it is a ArrayNode and the destination type is ArrayNode …

Any other idea ?


#18

Hi Eric,

I’ve not proof my solution. But the value you’ve via rest api isn’t typed “Object”, it’s from type “String”. So try this (without valueinfo)

“hdd” : {
“type” : “String”,
“value” : “[{“mntpoint”:“pv.01”,“size”:1,“ondisk”:}…blablabla… ]”
}

Cheers
setu


#19

Hi Eric & All,

I faced the similar issue. On form, before submit, I changed type to String and it worked.

    // set value in variable manager so that it can be sent to backend
    variableManager.variable('myObj').type = 'String';
    // variableManager.variableValue('myObj', JSON.stringify($scope.myObj));
});

--Alok Anand