Variable is not from type 'Collection'

Hi, I’m pretty new to Camunda and trying out some stuff.

I want to use a subprocess to iterate over a collection but cannot get it to work. When starting the process I get the exception Variable X is not from type ‘Collection’.
I’m using the Java SDK and it seems like my variable is set. Here is my model process.bpmn (9.1 KB)

I do:
Map<String, Object> variables = new HashMap<String, Object>();
Collection stringList= new ArrayList();
stringList.add(“Peter”);
stringList.add(“Paul”);
stringList.add(“Mary”);
variables.put(“TestCollection” , stringList);
processEngine.getRuntimeService().startProcessInstanceByKey( “FlakyTestDetector”, variables);

image

Camunda supports only Collection type. It won’t accept Map/List/Set. So you can convert it to Collection type object. Later if you would like to extract details from collection object you can configure task listeners to that task to process the data.

Try with:

Collection<String> coll;

or

Collection<Object> coll;

Thanks for the fast reply.
I’m not 100% sure what you mean by Collection Type. Collection is ‘just’ an interface. Which implementation can I use to store my objects? Do you have a simple example somewhere that shows how to go over a collection of objects in a subprocess?

@svenpet yes correct. You can assign the types whichever implements Collection interface.

For example, List, LinkedList, Vector & Set are implementations of collection interface. Map doesn’t implements collection interface. So you can assign like this:

String str = "Welcome,to,camunda";
Collection<String> coll = Arrays.asList(str.split(","));

List can hold any type of Object.

I get the same exception… Seems like I’m doing something else wrong:
I took your example, added coll to variables with the key “TestCollection”, and used “TestCollection” as Collection in the Transactional Subprocess… :man_shrugging:

variables.put(“TestCollection” , coll);
processEngine.getRuntimeService().startProcessInstanceByKey( “FlakyTestDetector”, variables);

Not sure, what I’m doing wrong…

@svenpet yes correct. You can assign the types whichever implements Collection interface.

For example, List, LinkedList, Vector & Set are implementations of collection interface. Map doesn’t implements collection interface. So you can assign like this:

String str = "Welcome,to,camunda";
Collection<String> coll = Arrays.asList(str.split(","));

List can hold any type of Object.

You need to do below things.

  1. When start process instance by key with variables use below snippet:

     Map<String, Object> variables = new HashMap<String, Object>();
     List<String> stringList= new ArrayList();
     stringList.add("Peter");
     stringList.add("Paul");
     stringList.add("Mary");
     variables.put("userList" , stringList);
     processEngine.getRuntimeService().startProcessInstanceByKey("FlakyTestDetector", variables);
    
  2. Use this ExecutionListener:

     import java.util.List;
    
     import org.camunda.bpm.engine.delegate.DelegateExecution;
     import org.camunda.bpm.engine.delegate.ExecutionListener;
     import org.camunda.bpm.engine.delegate.TaskListener;
    
     public class SubProcessListener implements ExecutionListener {
    
       @Override
       public void notify(DelegateExecution delegateExecution) throws Exception {
         if (delegateExecution.getEventName().equals(TaskListener.EVENTNAME_CREATE)) {
           List<String> testCollection = (List<String>) delegateExecution.getVariable("userList");
           delegateExecution.setVariable("testCollection", testCollection);
         }
       }
     }
    
  3. Made changes in your bpmn. Use this bpmn. Also check for package name configured in listener section in bpmn file. Based on your package name you can change it:
    process.bpmn (9.2 KB)