【问题标题】:Camunda external Java task: "Cannot deserialize object in variable"Camunda 外部 Java 任务:“无法反序列化变量中的对象”
【发布时间】:2022-10-08 14:20:47
【问题描述】:

我正在实现一个 Java ExternalTask​​Handler,来处理一个 Camunda 外部任务。作为任务的结果,我正在返回一个对象数组。不幸的是,当我返回这个数组时,我得到一个错误,即 Camunda 无法反序列化我的对象。

我的代码如下:

public class MyClass implements ExternalTaskHandler 
{
    public void execute(ExternalTask externalTask, ExternalTaskService externalTaskService) 
    {
        // Construct the returned object
        List<MyObject> myObjects = new ArrayList<MyObject>();
        myObjects.add(new MyObject());

        // Put it in the response
        Map<String,Object> returnedObjects = new HashMap<String,Object>();
        returnedObjects.put("myObjects", myObjects);

        // Finish the task -- this is where the error occurs
        externalTaskService.setVariables(externalTask, returnedObjects);
    }
}

错误如下:

TASK/CLIENT-01009 Exception while completing the external task: 
The corresponding process instance could not be resumed. Reason: status code: 500, reason phrase: 
{"type":"ProcessEngineException","message":"Cannot deserialize object in variable 'returnedObjects': SPIN/JACKSON-JSON-01007 Cannot construct java type from string 'java.util.ArrayList<my.test.MyObject>'","code":0}

有趣的是,如果我用字符串列表替换 MyObject 的列表,比如说,代码可以工作。

我应该添加或配置什么以允许 Camunda 成功反序列化我的对象?


编辑:这是MyObject 的实现:

public class MyObject
{
    private String name;
    
    private List<String> values;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

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

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

【问题讨论】:

  • 请添加my.test.MyObject的代码
  • @MichaelKatt 它里面有一个 List<String> 。而已。当然有一个 getter 和 setter。
  • 这是一个序列化或 camunda 知道你的班级的问题。因此,我要求您实施my.test.MyObject。是否使用接口Serializable 标记?场不是瞬态的吗?您是否使用自定义序列化?对于 Camunda:Camundo 知道你的班级吗?您是否将带有 my.test.MyObject 的 JAR 的依赖项添加到您的自定义 Camunda 部分?
  • @MichaelKatt 感谢您的回复。我已经用代码编辑了这个问题。

标签: java serialization camunda


【解决方案1】:

错误消息包含此提示

无法反序列化变量中的对象

如果你需要序列化/反序列化一个类,这个类必须实现接口java.io.Serializable。并且用于该类中的字段的任何类也必须实现接口Serializable

如题所示,你的类MyObject没有实现接口Serializable

public class MyObject {

现在查看MyObject 的字段

private String name;

String 实现 Serializable 因此 String 是可序列化的。

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {

private List<String> values;

由于接口List 及其继承的接口没有实现接口Serializable,它取决于List 的使用实现是否可序列化。 ArrayList 例如是可序列化的。

public interface List<E> extends Collection<E> {
public interface Collection<E> extends Iterable<E> {
public interface Iterable<T> {

public class ArrayList<E> extends AbstractList<E>
    implements List<E>, RandomAccess, Cloneable, java.io.Serializable

作为结论,您必须添加接口Serializable

公共类 MyObject 实现 Serializable

并且您必须使用List 的可序列化实现。

要了解有关序列化的更多信息,请访问Oracle guide serialization

【讨论】:

    【解决方案2】:

    虽然使您的对象可序列化在技术上可能是解决方案,但您不应该对流程数据使用 Java 序列化。

    在最近的 Camunda 7 版本中,Java 序列化已被弃用。原因包括语言依赖和紧耦合它创建。流程数据的不同消费者需要有可用的 Java 类。对它的每次更新都需要对访问数据的其他服务进行更新。可序列化的版本控制是另一个挑战......

    无论如何:你应该序列化为 JSON.这样任何客户端(Java 或非 Java)都可以处理数据,您可以轻松地处理人类可读格式的数据,可以使用不同的编程语言,可以使用 jsonPath 在过程中导航,具有更好的互操作性使用 DMN/FEEL,如果需要,可以在 UI 层轻松使用它,...并且准备得更好 -在 Camunda 8 JSON 是唯一支持的序列化FEEL 是表达语言(不再是 JUEL)。

    这是一个例子: https://github.com/rob2universe/c7-rest-task-worker/blob/bff52eccfe569dcd25f39231906f9e209c5b4467/src/main/java/com/camunda/example/worker/RESTWorker.java#L33

    【讨论】:

      猜你喜欢
      • 2013-01-04
      • 1970-01-01
      • 1970-01-01
      • 2015-01-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-12-06
      • 1970-01-01
      相关资源
      最近更新 更多