-
Notifications
You must be signed in to change notification settings - Fork 105
Description
Describe the bug
Custom serializers registered via @JsonbTypeSerializer annotation are not applied to properties declared as Object type but containing instances of the serializer's target type at runtime. The serializer only works for properties with the exact declared type matching the annotated class.
To Reproduce
import jakarta.json.bind.*;
import jakarta.json.bind.annotation.JsonbTypeSerializer;
import jakarta.json.bind.serializer.*;
import jakarta.json.stream.JsonGenerator;
public class SerializerBugDemo {
@JsonbTypeSerializer(MyClassSerializer.class)
public static class MyClass { }
public static class Container {
private final MyClass single = new MyClass();
private final Object singleAsObject = single; // Same instance, different declared type
public MyClass getSingle() { return single; }
public Object getSingleAsObject() { return singleAsObject; }
}
public static class MyClassSerializer implements JsonbSerializer<MyClass> {
@Override
public void serialize(MyClass obj, JsonGenerator generator, SerializationContext ctx) {
generator.write("MyClassSerialized");
}
}
public static void main(String[] args) {
try (Jsonb jsonb = JsonbBuilder.create()) {
Container container = new Container();
String result = jsonb.toJson(container);
System.out.println(result);
} catch (Exception e) {
e.printStackTrace();
}
}
}Expected behavior
The serializer should be applied to both properties:
{"single":"MyClassSerialized","singleAsObject":"MyClassSerialized"}The singleAsObject property should use the MyClassSerializer because at runtime it contains a MyClass instance, even though the property is declared as Object.
Actual behavior
{"single":"MyClassSerialized","singleAsObject":{}}The annotation-based serializer only works for the directly-typed property, not for the Object-typed property that contains the same instance.
System information:
- OS: Linux (reproduced on Fedora 43)
- Java Version: 17+
- Yasson Version: 3.0.4
Additional context
The bug occurs in ComponentMatcher.java in the getSerializerBinding() and getDeserializerBinding() methods. When a customization binding exists (from the annotation) but doesn't exactly match the runtime type, the methods return Optional.empty() instead of returning the customization binding.