From 64556ca8b59e43ec38ae6dc44e671bf46e306b4a Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Tue, 28 Oct 2025 18:31:29 -0400 Subject: [PATCH 1/2] fix custom adapter priority it seems that custom adapters could be overshadowed in some cases --- .../other/custom/CustomClashJsonAdapter.java | 41 +++++++++++++++++++ .../custom/CustomClashJsonAdapterTest.java | 25 +++++++++++ .../avaje/jsonb/generator/JsonbProcessor.java | 10 +++-- 3 files changed, 72 insertions(+), 4 deletions(-) create mode 100644 blackbox-test/src/main/java/org/example/other/custom/CustomClashJsonAdapter.java create mode 100644 blackbox-test/src/test/resources/org/example/other/custom/CustomClashJsonAdapterTest.java diff --git a/blackbox-test/src/main/java/org/example/other/custom/CustomClashJsonAdapter.java b/blackbox-test/src/main/java/org/example/other/custom/CustomClashJsonAdapter.java new file mode 100644 index 00000000..8932b9ce --- /dev/null +++ b/blackbox-test/src/main/java/org/example/other/custom/CustomClashJsonAdapter.java @@ -0,0 +1,41 @@ +package org.example.other.custom; + +import java.lang.reflect.Type; +import java.util.List; + +import io.avaje.json.JsonAdapter; +import io.avaje.json.JsonReader; +import io.avaje.json.JsonWriter; +import io.avaje.jsonb.AdapterFactory; +import io.avaje.jsonb.CustomAdapter; +import io.avaje.jsonb.Json; +import io.avaje.jsonb.Jsonb; +import io.avaje.jsonb.Types; + +@CustomAdapter +public class CustomClashJsonAdapter + implements JsonAdapter> { + + public static final AdapterFactory FACTORY = + (type, jsonb) -> { + if (Types.isGenericTypeOf(type, NestedGeneric.class)) { + return new CustomClashJsonAdapter<>(jsonb, Types.typeArguments(type)); + } + return null; + }; + + public CustomClashJsonAdapter(Jsonb jsonb, Type[] types) {} + + public record NestedGeneric(T value) {} + + @Json + public record NestedGeneric2(List> value) {} + + @Override + public void toJson(JsonWriter writer, NestedGeneric value) {} + + @Override + public NestedGeneric fromJson(JsonReader reader) { + return null; + } +} diff --git a/blackbox-test/src/test/resources/org/example/other/custom/CustomClashJsonAdapterTest.java b/blackbox-test/src/test/resources/org/example/other/custom/CustomClashJsonAdapterTest.java new file mode 100644 index 00000000..1e44046d --- /dev/null +++ b/blackbox-test/src/test/resources/org/example/other/custom/CustomClashJsonAdapterTest.java @@ -0,0 +1,25 @@ +package org.example.other.custom; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.*; + +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +import io.avaje.jsonb.Jsonb; +import io.avaje.jsonb.Types; + +class CustomClashJsonAdapterTest { + + @Test + void test() { + assertThat(Jsonb.instance().adapter(CustomClashJsonAdapter.NestedGeneric.class)) + .isInstanceOf(CustomClashJsonAdapter.class); + + assertThat( + Jsonb.instance() + .adapter(Types.newParameterizedType(CustomClashJsonAdapter.class, String.class))) + .isInstanceOf(CustomClashJsonAdapter.class); + } +} diff --git a/jsonb-generator/src/main/java/io/avaje/jsonb/generator/JsonbProcessor.java b/jsonb-generator/src/main/java/io/avaje/jsonb/generator/JsonbProcessor.java index 939e26e8..0e9dd650 100644 --- a/jsonb-generator/src/main/java/io/avaje/jsonb/generator/JsonbProcessor.java +++ b/jsonb-generator/src/main/java/io/avaje/jsonb/generator/JsonbProcessor.java @@ -4,10 +4,12 @@ import static io.avaje.jsonb.generator.APContext.logError; import static io.avaje.jsonb.generator.APContext.logNote; import static io.avaje.jsonb.generator.APContext.typeElement; -import static io.avaje.jsonb.generator.Constants.*; +import static io.avaje.jsonb.generator.Constants.JSON; +import static io.avaje.jsonb.generator.Constants.JSON_IMPORT; +import static io.avaje.jsonb.generator.Constants.JSON_IMPORT_LIST; +import static io.avaje.jsonb.generator.Constants.JSON_MIXIN; import static io.avaje.jsonb.generator.ProcessingContext.addImportedPrism; import static io.avaje.jsonb.generator.ProcessingContext.createMetaInfWriterFor; -import static io.avaje.jsonb.generator.ValuePrism.*; import static java.util.stream.Collectors.joining; import java.io.IOException; @@ -115,8 +117,6 @@ public boolean process(Set annotations, RoundEnvironment } APContext.setProjectModuleElement(annotations, round); readModule(); - - getElements(round, CustomAdapterPrism.PRISM_TYPE).ifPresent(this::registerCustomAdapters); getElements(round, ValuePrism.PRISM_TYPE).ifPresent(this::writeValueAdapters); getElements(round, JSON).ifPresent(this::writeAdapters); getElements(round, JSON_MIXIN).ifPresent(this::writeAdaptersForMixInTypes); @@ -126,6 +126,8 @@ public boolean process(Set annotations, RoundEnvironment metaData.fullName(false); cascadeTypes(); + getElements(round, CustomAdapterPrism.PRISM_TYPE).ifPresent(this::registerCustomAdapters); + writeComponent(round.processingOver()); return false; } From e15088758c241ae47b1d39686b3c008e275e25f9 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Tue, 28 Oct 2025 18:36:54 -0400 Subject: [PATCH 2/2] Update JsonbProcessor.java --- .../src/main/java/io/avaje/jsonb/generator/JsonbProcessor.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/jsonb-generator/src/main/java/io/avaje/jsonb/generator/JsonbProcessor.java b/jsonb-generator/src/main/java/io/avaje/jsonb/generator/JsonbProcessor.java index 0e9dd650..e081aa78 100644 --- a/jsonb-generator/src/main/java/io/avaje/jsonb/generator/JsonbProcessor.java +++ b/jsonb-generator/src/main/java/io/avaje/jsonb/generator/JsonbProcessor.java @@ -123,11 +123,10 @@ public boolean process(Set annotations, RoundEnvironment getElements(round, JSON_IMPORT_LIST).ifPresent(this::writeAdaptersForImportedList); getElements(round, JSON_IMPORT).ifPresent(this::writeAdaptersForImported); getElements(round, "io.avaje.spi.ServiceProvider").ifPresent(this::registerSPI); + getElements(round, CustomAdapterPrism.PRISM_TYPE).ifPresent(this::registerCustomAdapters); metaData.fullName(false); cascadeTypes(); - getElements(round, CustomAdapterPrism.PRISM_TYPE).ifPresent(this::registerCustomAdapters); - writeComponent(round.processingOver()); return false; }