How to manually deserialise the x-java-serialized-object text

Hi @firstpostcommenter,

You’re running into a common scenario when dealing with Camunda variable serialization. Let’s tackle both of your questions in turn:


1. Why use Variables.objectValue(...).serializationDataFormat(...) instead of setting the value directly?

You’re right that in many cases you can just do:

execution.setVariable("varName", productDetails)

But the explicit approach using Variables.objectValue(...) is used for control and clarity around serialization. Here’s the breakdown:

When to use the explicit Variables.objectValue() form:

  • You want to explicitly specify the serialization format (e.g., JSON vs. Java Serialized Object).
  • You want to avoid fallback to default Java serialization, which is what Camunda may use when it doesn’t know how to serialize a complex type.
  • You’re storing custom classes or complex types, and you want to ensure they’re portable and readable (e.g., for Cockpit, REST API, etc).

Why the direct approach may not always work:

  • If Camunda doesn’t know how to serialize the object, or can’t infer a format, it may default to application/x-java-serialized-object.
  • This leads to exactly the kind of issue you’re now trying to avoid: non-human-readable format, class loading issues, etc.

So in summary:

You can use the short version if you’re confident that your object is simple (e.g., Map<String, String>), and that Camunda’s default object mapper is properly configured to serialize it as JSON.
But for robustness and clarity, it’s best to be explicit—especially in a production system or when dealing with process variables that might be viewed in Cockpit or via REST.


2. How to deserialize x-java-serialized-object manually to see its contents in Java?

Yes, you can deserialize it using Java’s ObjectInputStream. Here’s how you can do it manually:

import java.io.*;
import java.util.Map;

public class DeserializeCamundaObject {
    public static void main(String[] args) throws Exception {
        // This is your serialized base64 string from Camunda
        String base64Serialized = "rO0ABXNyABFqYXZhLnV0aWwuSGFzaE1hcAAAAAAAAAABDAAAeHB3BAAAAAB4";

        // Decode base64 to bytes
        byte[] data = java.util.Base64.getDecoder().decode(base64Serialized);

        // Deserialize
        try (ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(data))) {
            Object obj = ois.readObject();
            
            // Now you can cast and inspect it
            if (obj instanceof Map) {
                Map<?, ?> map = (Map<?, ?>) obj;
                System.out.println("Deserialized Map:");
                map.forEach((k, v) -> System.out.println(k + " -> " + v));
            } else {
                System.out.println("Deserialized Object: " + obj);
            }
        }
    }
}

:warning: Important Notes:

  • This only works if the classes involved are present on the classpath. If the object being deserialized references a custom class, that class must be available.
  • It’s a good idea to move away from this format (as you plan to) and use JSON for better portability and inspection.

1 Like