Apply review suggestions Test a class-level @JsonbTypeSerializer inside a collection and directly, in that order. ComponentMatcher already finds such a serializer since #689, so take only an adapter from the customization of the runtime class, and keep the customization of the declared type when it binds a serializer or an adapter. Signed-off-by: Sharang Gupta <sharang@sharanggupta.dev>
diff --git a/src/main/java/org/eclipse/yasson/internal/serializer/SerializationModelCreator.java b/src/main/java/org/eclipse/yasson/internal/serializer/SerializationModelCreator.java index b42d947..cb49652 100644 --- a/src/main/java/org/eclipse/yasson/internal/serializer/SerializationModelCreator.java +++ b/src/main/java/org/eclipse/yasson/internal/serializer/SerializationModelCreator.java
@@ -124,27 +124,25 @@ /** * Return the customization to create the serializer of a type only known at runtime with. * The given customization is the one of the declared type, for example {@link Object} for the elements of a raw - * collection, so a serializer or an adapter bound to the class of the runtime type, for example with - * {@code @JsonbTypeAdapter} on the class, is taken from the customization of that class when the given - * customization does not bind one. + * collection, so an adapter bound to the class of the runtime type with {@code @JsonbTypeAdapter} is taken from + * the customization of that class when the given customization binds neither a serializer nor an adapter. + * A serializer bound to the class with {@code @JsonbTypeSerializer} is already found by + * {@link ComponentMatcher#getSerializerBinding}. * * @param runtimeType runtime type of the value * @param customization customization of the declared type * @return customization to use */ private Customization runtimeTypeCustomization(Class<?> runtimeType, Customization customization) { - if (bindsSerializationComponent((ComponentBoundCustomization) customization)) { + ComponentBoundCustomization declared = (ComponentBoundCustomization) customization; + if (declared != null + && (declared.getSerializerBinding() != null || declared.getSerializeAdapterBinding() != null)) { return customization; } ClassCustomization classCustomization = jsonbContext.getMappingContext() .getOrCreateClassModel(runtimeType) .getClassCustomization(); - return bindsSerializationComponent(classCustomization) ? classCustomization : customization; - } - - private static boolean bindsSerializationComponent(ComponentBoundCustomization customization) { - return customization != null - && (customization.getSerializerBinding() != null || customization.getSerializeAdapterBinding() != null); + return classCustomization.getSerializeAdapterBinding() != null ? classCustomization : customization; } private ModelSerializer serializerChain(LinkedList<Type> chain,
diff --git a/src/test/java/org/eclipse/yasson/adapters/JsonbTypeAdapterTest.java b/src/test/java/org/eclipse/yasson/adapters/JsonbTypeAdapterTest.java index 0440178..4bfb142 100644 --- a/src/test/java/org/eclipse/yasson/adapters/JsonbTypeAdapterTest.java +++ b/src/test/java/org/eclipse/yasson/adapters/JsonbTypeAdapterTest.java
@@ -152,6 +152,7 @@ @Test public void testClassAdapterOfCollectionElement() throws Exception { + // Must use a new Jsonb instance to make sure adapter cache is empty try (Jsonb jsonb = JsonbBuilder.create()) { assertEquals("[\"adapted\"]", jsonb.toJson(List.of(new AnnotatedType()))); assertEquals("\"adapted\"", jsonb.toJson(new AnnotatedType()));
diff --git a/src/test/java/org/eclipse/yasson/serializers/SerializersTest.java b/src/test/java/org/eclipse/yasson/serializers/SerializersTest.java index 8214b88..26a829a 100644 --- a/src/test/java/org/eclipse/yasson/serializers/SerializersTest.java +++ b/src/test/java/org/eclipse/yasson/serializers/SerializersTest.java
@@ -1,5 +1,6 @@ /* * Copyright (c) 2016, 2025 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2026 Contributors to the Eclipse Foundation * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0 which is available at @@ -839,6 +840,27 @@ } + @JsonbTypeSerializer(SerializedTypeSerializer.class) + public static class SerializedType { + public String field = "value"; + } + + public static class SerializedTypeSerializer implements JsonbSerializer<SerializedType> { + @Override + public void serialize(SerializedType obj, JsonGenerator generator, SerializationContext ctx) { + generator.write("serialized"); + } + } + + @Test + public void testClassSerializerOfCollectionElement() throws Exception { + // Must use a new Jsonb instance to make sure serializer cache is empty + try (Jsonb jsonb = JsonbBuilder.create()) { + assertEquals("[\"serialized\"]", jsonb.toJson(List.of(new SerializedType()))); + assertEquals("\"serialized\"", jsonb.toJson(new SerializedType())); + } + } + /** * Test that annotation-based serializers work when property is declared as Object * but the runtime type has @JsonbTypeSerializer annotation.