Class cast exception object

Hi all,

We have developed a simple bpmn process where one servicetask generates a list of objects and updates the process variable by executing

client.newCompleteCommand(job.getKey()).variables(processVariables).send().join()

The processVariables is a Hashmap defined as below:
Map<String, Object> processVariables= new HashMap<String, Object>();

Within the HashMap we have added a List of objects like below, where the list contains 3 instances of object type OrderRequest

    List<OrderRequest> orderRequests= new ArrayList<OrderRequest>();
    processVariables.put("orderRequests", orderRequests);

The worker is completed successfully and the variable is depicted correctly in simple monitor app.
After this we try within a subsequent service task to read one entry from the list using


    ArrayList<OrderRequests> orderRequests=
        (ArrayList<OrderRequests>) job.getVariablesAsMap().get("orderRequests");

    System.out.println(orderRequests.get(0).getOrderRequestId());

but the last expression fails with
java.lang.ClassCastException: class java.util.LinkedHashMap cannot be cast to class OrderRequest.

Is there any other way where we can write a list of objects as a process variable and read the elements of the list as objects correctly in a subsequent service task?
Are only list of primitives retrieved correctly from workers?

OrderRequest class contains three String variables and getters/setters

public class OrderRequest {
  
  private String orderRequestId;
  private String orderRequestNumber;
  private String orderRequestStatus;
}

Hello @ntheodoropoulos ,

you can use job.getVariablesAsType(ProcessVariables.class) where all process variables will be deserialized explicitly to the provided type.

In your case, this would mean that you need a class containing a field type List < OrderRequest > and name orderRequests.

Then, you can let the ObjectMapper do its magic.

Oh, btw the reason is that in C8, everything is plain json, no type or other meta information is added to process variables.

I hope this helps

Jonathan

Hi @jonathan.lukas ,

Thanks for the feedback!
I made a test and the proposed solution works.
An additional question. The job.getVariablesAsType method does not provide an input argument for specifying the variable that needs to be retrieved.

  1. In case we have multiple variables with different object types/or simple primitives, how does this work internally, does it simply ignore all other variables?
  2. If we have two different process variables variable1 and variable2 with the same object type, which one of the variables will it fetch, one randomly. Through testing I think it fetches the first one in ascending alphabetical order?
    In such a case how can we overcome the issue? Would we need to save the variable as String ,retrieve the variable as string and use custom Jackson code to desereliaze it afterwards to Java object?
  3. Technically could the zeebe client API be modified, so that we could specify which variable to fetch and provide some meta information (such as the object type, or even a List<ObjectType.class>) so that variables could be deserialized correctly as objects?

Hello @ntheodoropoulos ,

the intention of getVariablesAsType(type) is to deserialize ALL variables to an object.

Given you have variables

{
  "foo": "bar",
  "bif": 3
}

you could create a class

public class MyVariables {
  private String foo;
  private Integer bif;
  
  // getters and setters
}

and then call

MyVariables variables = job.getVariablesAsType(MyVariables.class);
String foo = variables.getFoo() // will return bar
Integer bif = variables.getBif() // will return 3

This will also work for more complex scenarios where a variable value is an object as in the background, a normal objectMapper is working.

  1. It will use the settings of the ObjectMapper used, but by default, it should ignore variables that exist but are not declared in your type.

  2. It will fetch both, you will have to create 2 fields for them.

  3. You could, but the variables as type feature is better :wink:

Jonathan

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