Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Afterburner breaks serialization of ObjectMapper #97

Closed
zman0900 opened this issue May 23, 2020 · 4 comments
Closed

Afterburner breaks serialization of ObjectMapper #97

zman0900 opened this issue May 23, 2020 · 4 comments
Milestone

Comments

@zman0900
Copy link

JsonMapper and its parent class ObjectMapper are both supposed to be Serializable, but when AfterburnerModule is added, serialization is no longer possible.

For example, this code:

public class SerTest {
    public static void main(final String... args) throws Exception {
        final JsonMapper x = JsonMapper.builder()
                .addModule(new AfterburnerModule())
                .build();

        final ByteArrayOutputStream out = new ByteArrayOutputStream();
        new ObjectOutputStream(out)
                .writeObject(x);

        final ObjectInputStream input = new ObjectInputStream(new ByteArrayInputStream(out.toByteArray()));
        final JsonMapper y = (JsonMapper) input.readObject();
    }
}

Results in exception:

Exception in thread "main" java.io.NotSerializableException: com.fasterxml.jackson.module.afterburner.deser.DeserializerModifier
	at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1184)
	at java.io.ObjectOutputStream.writeArray(ObjectOutputStream.java:1378)
	at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1174)
	at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1548)
	at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1509)
	at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1432)
	at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178)
	at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1548)
	at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1509)
	at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1432)
	at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178)
	at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1548)
	at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1509)
	at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1432)
	at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178)
	at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1548)
	at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1509)
	at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1432)
	at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178)
	at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:348)
	at SerTest.main(SerTest.java:13)

Without adding the AfterburnerModule to JsonMapper, this works as expected.

Jackson version = 2.11.0

@cowtowncoder
Copy link
Member

Thank you for reporting this: yes, modules should be serializable (there is one known exception for 2.x, Java 8 date/time module; but those are exceptions to the rule and Afterburner not known as one).

One quick question: do you know if this is a regression (used to work), or just observed now?

@cowtowncoder cowtowncoder added this to the 2.11. milestone May 24, 2020
@cowtowncoder cowtowncoder modified the milestones: 2.11., 2.11.1 May 24, 2020
@cowtowncoder
Copy link
Member

cowtowncoder commented May 24, 2020

Ok. So, was able to make serializability work in 2.11(.1) as long as ObjectMapper serialized BEFORE any use of Afterburner (that is, readValue, writeValue that triggers class generation).
This is the general best practice anyway (serializable after configuration, before use) but I thought it good to mention.

Jackson 3.0 will actually change the limit as JDK serialization of ObjectMapper is limited to only serializing configuration, not state (based on big refactoring of how construction of mapper works with builders): it will not matter if usage has occurred. But 2.x has this limitation.

@zman0900
Copy link
Author

I've never tried it in previous versions. I've worked around it for now by just using a static variable. I was trying to have Spring create and configure the JsonMapper, which would then be used in a map function for Spark, but those must be serializable.

@cowtowncoder
Copy link
Member

@zman0900 Makes sense. Serializing ObjectMapper is often best avoided but intent is for JDK serialization to work for mapper, modules, as sometimes it is still needed.

As per my notes this will be fixed in 2.11.1, as long as pattern of config-only-before-serialization/deserialization is followed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants