Put/get java object on process with java delegate

Do you have any examples on how to put an java object on the process with java delegate, and in a later task retrieve it and add values to it, before adding it to the process again?

Hi @FrankReneSorensen,

this seems like a very basic question, so I suggest you take a look at the Camunda Getting Started Tutorials.

But in general when you are working with JavaDelegates you can do the following:

Set an object as process variable:

execution.setVariable(“variableName”, variable);

Get a process variable:

execution.getVariable(“variableName”);

Hope this helps

Regards
Michael

@MichiDahm

Hi Michi!

Thanks for your answer.

I agree, it seems simple. But, I try to put an java class, with lists, etc. i get an error saying:
Cannot find serializer for value 'Untyped value

Here is my code when I try to add the object to the process:

Test test = new Test();
test.addStringTestValue(“some value”)
ObjectValue typedObjectValue = Variables
.objectValue(test)
.serializationDataFormat(Variables.SerializationDataFormats.JAVA)
.create();
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
RuntimeService runtimeService = processEngine.getRuntimeService();

runtimeService.setVariable(execution.getId(), “test”, test);

ObjectValue retrievedTypedObjectValue = runtimeService.getVariableTyped(execution.getId(), “test”);
Test test2 = (Test) retrievedTypedObjectValue.getValue();

I get this error when I run this:

ENGINE-16004 Exception while closing command context: Cannot find serializer for value 'Untyped value ’
I would be grateful for any help with this.

Frank

@MichiDahm

It seems like this setVariable and getVariable only works for String, int, etc.

I need to put an custom java object in the process instance.

@FrankReneSorensen

Is there a specific reason why you are using the Object Value Serialization?

As of this page in the docs the default way should be to simply use set and getVariable and the engine handles the rest.

Have you tried:

Test test = new Test();
test.addStringTestValue(“some value”)

ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
RuntimeService runtimeService = processEngine.getRuntimeService();

runtimeService.setVariable(execution.getId(), “test”, test);

Test newTest = (Test) runtimeService.getVariable(execution.getId(), “test”);

This should be the default way to work with the DelegateExecution.

Your way should be used if you explicitly want to specify a serialization format (and then your classes have to implement java.io.Serializable)

Regards
Michael

@MichiDahm

Hi

I still get this message:

Cannot find serializer for value 'Untyped value 'no.camunda.Test@5d9ebd81

In which context do you execute your code? Is that a JavaDelegate or an ExecutionListener or something entirely different?

Some contexts do not support all serializations, e.g. you cannot pass a JSON Object processvariable to the rest engine, it expects a JSON String. Hence the question about the context.

@dschulten

Hi. I use delegate expression. But even if I use java delegate, I am not able to put the object on the process.

I think the problem has to do with the serializer.

Can you please upload the exception stack trace? It seems there is no problem with a serializer, but Camunda can’t find a serializer in the first place. We need to find out why.

Here is the error when I try to start the process from tasklist and the first system task tries to add the object to the process:

The process could not be started. : Cannot instantiate process definition Casework:1:2ade8040-44a8-11e9-acb5-0e2c67acf8dd: Cannot find serializer for value ‘Untyped value ‘test.TestDTO@5c1d8d7a’, isTransient = false’.

Sorry, here is the correct stacktrace:

stacktrace.txt (46.0 KB)

@dschulten

Does the class have to implement Serializable?

The class I am using is not serializable. However, I just realized that I set my variable through a message correlation. Let me try to reproduce your case.

Your Test class is a pojo with all setters and getters, right? Without setters and getters for all members Camunda might have difficulty creating the instance and reading its content.

public class Test {
  private List<String> values = new ArrayList<>();

  public void addStringTestValue(String s) {
      values.add(s);
  }

  public List<String> getValues() {
      return values;
  }

  public void setValues(List<String> values) {
      this.values = values;
  }
}

Actually, when I added Serializable to the TestObject, the setVariable doesnt complain anymore.

But, in the next task, where I am trying to get the object with

TestDTO testDTO = (TestDTO) execution.getVariable(“testDTO”);

It gives the following exception:

class test.TestDTO cannot be cast to class test.TestDTO test.TestDTO is in unnamed module of loader ‘app’

I cannot reproduce your problem. My JavaDelegate sets the variable. When I inspect the process instance in Cockpit, it has the “test” variable.
Something strange is going on here. What version of Camunda do you use, and have you added any custom configurations to the process engine? Do you use the correct version of spring-boot with the matching camunda-bpm-spring-boot-starter-webapp version?
See https://docs.camunda.org/manual/latest/user-guide/spring-boot-integration/version-compatibility/

Hi @FrankReneSorensen,

I stumbeld once about this and it was a classloader issue with the spring-boot application running inside the IDE. (Black magic happening there)

If you build it with mvn clean package and run it from the command line, it should be fine.

Hope this helps, Ingo

Can you debug org.camunda.bpm.engine.impl.variable.serializer.DefaultVariableSerializers#findSerializerForValue()?
My Test class comes in as UntypedValueImpl, my serializerList has 15 serializers,
and the matching one is the SpinObjectValueSerializer.

I have added the following dependencies in my pom, maybe that is required:

    <dependency>
        <groupId>org.camunda.bpm</groupId>
        <artifactId>camunda-engine-plugin-spin</artifactId>
    </dependency>
    <dependency>
            <groupId>org.camunda.spin</groupId>
            <artifactId>camunda-spin-dataformat-json-jackson</artifactId>
    </dependency>

@Ingo_Richtsmeier @dschulten

Hi

Then it actually works. I had to add serializer to the main object and the list object in that class. Also have tp run the application outside of intellij to avoid the “unamed module” error.

I want to thank you very much for your help!

I will create an anonymous project and add it to git as soon as I have the time. So you can see how it works for me.

Br

Frank

2 Likes

Hi
I am working on camnda wokflow application

I need Help for wriing the test cases

How verify the value
Mockito.verify(execution, times(1)).setVariable(“data”, objectValue);

I tried the put Object value but in actulally we are serilize the Object and set the Value

ObjectValue objectValue = Variables.objectValue(sitesAndServicesUploadVariable)
.serializationDataFormat(Variables.SerializationDataFormats.JAVA)
.create();
execution.setVariable(“data”, objectValue);

Please let me know any on how to test the serializationDataFormat object in Junit