Deserialize org.camunda.bpm.engine.variable.VariableMap

Hi all!

In my project i use externalTaskService java api

List<LockedExternalTask> taskList = camunda.getExternalTaskService()
                    .fetchAndLock(100, EXTERNAL_WORKER_ID)
                    .topic(topic, 1L)
                    .execute();

ExternalTaskDataDto dto = ExternalTaskDataDto.builder()
                        .taskId(lockedExternalTask.getId())
                        .processDefinitionId(lockedExternalTask.getProcessDefinitionId())
                        .processInstanceId(lockedExternalTask.getProcessInstanceId())
                        .activityId(lockedExternalTask.getActivityId())
                        .activityInstanceId(lockedExternalTask.getActivityInstanceId())
                        .variables(lockedExternalTask.getVariables())
                        .build();

then ExternalTaskDataDto send to apache kafka topic, which is used by opposite side

on remote side i want to receive the message from kafka and handle it.

but, i have an error message about deserialize

2023-09-27 21:03:01.204 ERROR 69701 --- [container-0-C-1] o.s.integration.handler.LoggingHandler : org.springframework.messaging.MessageHandlingException: error occurred in message handler [org.springframework.cloud.stream.function.FunctionConfiguration$FunctionToDestinationBinder$1@15256482]; nested exception is java.lang.RuntimeException: com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot find a deserializer for non-concrete Map type [map type; class org.camunda.bpm.engine.variable.VariableMap, [simple type, class java.lang.String] -> [simple type, class java.lang.Object]]

on serviceA I use the following starter

		<dependency>
			<groupId>org.camunda.community.rest</groupId>
			<artifactId>camunda-platform-7-rest-client-spring-boot-starter</artifactId>
			<version>7.19.0</version>
		</dependency>

so i can use VariableMap class from camunda.

Help please, how to deserialize VariableMap?
Thanks for any ideas.

ps. i hope you understand me, sorry for my english :slight_smile:

Hello my friend!

Do you have any default (empty) constructors in your ExternalTaskDataDto class?

I ask this because Jackson uses reflection “under the hood”, instantiating the class without passing parameters, and only after this does Jackson fill in the attributes through reflection.

So if you don’t declare a constructor, Java itself creates a default, but as we are talking about a DTO, you must have declared a constructor that receives the entity as a parameter, so you must declare another constructor without arguments so that Jackson can work correctly.

I hope this is it and that I was able to help you.

William Robert Alves

Hello!

Yes, there is a default constructor

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor(access = PRIVATE)
public class ExternalTaskDataDto {
    private String taskId;
    private String processDefinitionId;
    private String processInstanceId;
    private String activityId;
    private String activityInstanceId;
    private VariableMap variables;
}

Hi @moshell ,

VariableMap is an interface and thus cannot be instantiated directly by Jackson without any hints what implementation should be used. Please try to use VariableMapImpl instead.

Otherwise, you could use Jackson`default typing mechanism to preserve the typing. See this post on Stackoverflow: json - How to customize Jackson type information mechanism - Stack Overflow.

Kind regards
Adagatiya

1 Like

Adagatiya, thank you =)

1 Like

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.