Skip to content

JsonMappingException not Serializable due to 2.7 reference to underlying parser #1195

@mjustin

Description

@mjustin

JsonMappingExceptions thrown by the Jackson parser cannot be serialized. This breaks any code that assumes the exception (per the Serializable interface it implements) is serializable.

Since the exception contains a reference to a non-serializable parser (such as com.fasterxml.jackson.core.json.ReaderBasedJsonParser), serialization will throw a NotSerializableException. Furthermore, the parser may contain a reference to the class being parsed; if that class is not itself serializable, that too will prevent serialization.

The expected behavior would be that these exceptions would be serializable.

I ran across this issue when testing some code with a missing subtype. The following code will replicate this issue:

import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.io.ByteArrayOutputStream;
import java.io.NotSerializableException;
import java.io.ObjectOutputStream;

public class SerializationTest {
    public static void main(String[] args) throws Exception {
        try {
            new ObjectMapper().readValue("{\"type\": \"B\"}", ClassToRead.class);
        } catch (JsonMappingException e) {
            try (ObjectOutputStream stream = new ObjectOutputStream(new ByteArrayOutputStream())) {
                stream.writeObject(e);
            } catch (NotSerializableException e2) {
                // java.io.NotSerializableException: com.fasterxml.jackson.core.json.ReaderBasedJsonParser
                System.err.println("Unable to serialize exception " + e);
                e2.printStackTrace();
            }
        }
        try {
            new ObjectMapper().readValue("{\"classToRead\": {\"type\": \"B\"}}", ContainerClassToRead.class);
        } catch (JsonMappingException e) {
            try (ObjectOutputStream stream = new ObjectOutputStream(new ByteArrayOutputStream())) {
                stream.writeObject(e);
            } catch (NotSerializableException e2) {
                // java.io.NotSerializableException: jackson.ContainerClassToRead
                System.err.println("Unable to serialize exception " + e);
                e2.printStackTrace();
            }
        }
    }
}

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property="type")
@JsonSubTypes({
        @JsonSubTypes.Type(value = SubclassToRead.class, name = "A")
})
abstract class ClassToRead {}
class SubclassToRead extends ClassToRead {}

class ContainerClassToRead {
    public ClassToRead classToRead;
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions