From 4eae6c272fb909b5b04b1bc562d8dc3eb734740e Mon Sep 17 00:00:00 2001 From: "robin.bygrave" Date: Tue, 12 Aug 2025 21:26:36 +1200 Subject: [PATCH 1/3] For collection types List, Set, Map use equals() rather than isAssignable() - To support Guava ImmutableList etc When using isAssignable(), the specialised collection types like Guava ImmutableList get treated like java.util.List and this means that we don't end up using any Custom JsonAdapter that we define for those special types. Changing to use equals() means that we really expect the java.util List|Set|Map collection types to be used and no ArrayList, LinkedList etc (which would have kind of worked before but not really in that they all would have ended up as ArrayList, LinkedHashSet, LinkedHashMap. So using equals() here should be ok. --- .../java/io/avaje/jsonb/generator/GenericType.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/jsonb-generator/src/main/java/io/avaje/jsonb/generator/GenericType.java b/jsonb-generator/src/main/java/io/avaje/jsonb/generator/GenericType.java index 46c3a31a..075a8865 100644 --- a/jsonb-generator/src/main/java/io/avaje/jsonb/generator/GenericType.java +++ b/jsonb-generator/src/main/java/io/avaje/jsonb/generator/GenericType.java @@ -167,22 +167,22 @@ private String asTypeBasic() { if (adapterType != null) { return adapterType; } - return Util.shortName(topType)+".class"; + return Util.shortName(topType) + ".class"; } private String asTypeContainer() { GenericType param = params.get(0); String containerType = topType(); - if (isAssignable(containerType, "java.util.List")) { + if ("java.util.List".equals(containerType)) { return "Types.listOf(" + Util.shortName(param.topType()) + ".class)"; } - if (isAssignable(containerType, "java.util.Set")) { + if ("java.util.Set".equals(containerType)) { return "Types.setOf(" + Util.shortName(param.topType()) + ".class)"; } - if (isAssignable(containerType, "java.util.stream.Stream")) { + if ("java.util.stream.Stream".equals(containerType)) { return "Types.streamOf(" + Util.shortName(param.topType()) + ".class)"; } - if (isAssignable(containerType, "java.util.Optional")) { + if ("java.util.Optional".equals(containerType)) { return "Types.optionalOf(" + Util.shortName(param.topType()) + ".class)"; } return null; From a44370c8dd6ee83773ba272fab5032c3ca17d10e Mon Sep 17 00:00:00 2001 From: "robin.bygrave" Date: Tue, 12 Aug 2025 21:31:46 +1200 Subject: [PATCH 2/3] Support ArrayList and LinkedHashSet as these are the underlying implementations so also valid --- .../src/main/java/io/avaje/jsonb/generator/GenericType.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/jsonb-generator/src/main/java/io/avaje/jsonb/generator/GenericType.java b/jsonb-generator/src/main/java/io/avaje/jsonb/generator/GenericType.java index 075a8865..e9e880cf 100644 --- a/jsonb-generator/src/main/java/io/avaje/jsonb/generator/GenericType.java +++ b/jsonb-generator/src/main/java/io/avaje/jsonb/generator/GenericType.java @@ -173,10 +173,10 @@ private String asTypeBasic() { private String asTypeContainer() { GenericType param = params.get(0); String containerType = topType(); - if ("java.util.List".equals(containerType)) { + if ("java.util.List".equals(containerType) || "java.util.ArrayList".equals(containerType)) { return "Types.listOf(" + Util.shortName(param.topType()) + ".class)"; } - if ("java.util.Set".equals(containerType)) { + if ("java.util.Set".equals(containerType) || "java.util.LinkedHashSet".equals(containerType)) { return "Types.setOf(" + Util.shortName(param.topType()) + ".class)"; } if ("java.util.stream.Stream".equals(containerType)) { From c69703a79bd0657354f3c5d4350f0941ad4a2daf Mon Sep 17 00:00:00 2001 From: "robin.bygrave" Date: Tue, 12 Aug 2025 21:46:00 +1200 Subject: [PATCH 3/3] Add tests for ArrayList and LinkedHashSet --- .../example/customer/stream/MyArrayList.java | 9 ++++++ .../org/example/customer/stream/MyLinked.java | 9 ++++++ .../customer/stream/MyArrayListTest.java | 30 +++++++++++++++++++ .../customer/stream/MyLinkedHashSetTest.java | 28 +++++++++++++++++ 4 files changed, 76 insertions(+) create mode 100644 blackbox-test/src/main/java/org/example/customer/stream/MyArrayList.java create mode 100644 blackbox-test/src/main/java/org/example/customer/stream/MyLinked.java create mode 100644 blackbox-test/src/test/java/org/example/customer/stream/MyArrayListTest.java create mode 100644 blackbox-test/src/test/java/org/example/customer/stream/MyLinkedHashSetTest.java diff --git a/blackbox-test/src/main/java/org/example/customer/stream/MyArrayList.java b/blackbox-test/src/main/java/org/example/customer/stream/MyArrayList.java new file mode 100644 index 00000000..d43b7214 --- /dev/null +++ b/blackbox-test/src/main/java/org/example/customer/stream/MyArrayList.java @@ -0,0 +1,9 @@ +package org.example.customer.stream; + +import io.avaje.jsonb.Json; + +import java.util.ArrayList; + +@Json +public record MyArrayList(int id, ArrayList names) { +} diff --git a/blackbox-test/src/main/java/org/example/customer/stream/MyLinked.java b/blackbox-test/src/main/java/org/example/customer/stream/MyLinked.java new file mode 100644 index 00000000..4473aff0 --- /dev/null +++ b/blackbox-test/src/main/java/org/example/customer/stream/MyLinked.java @@ -0,0 +1,9 @@ +package org.example.customer.stream; + +import io.avaje.jsonb.Json; + +import java.util.LinkedHashSet; + +@Json +public record MyLinked(int id, LinkedHashSet names) { +} diff --git a/blackbox-test/src/test/java/org/example/customer/stream/MyArrayListTest.java b/blackbox-test/src/test/java/org/example/customer/stream/MyArrayListTest.java new file mode 100644 index 00000000..2a94c936 --- /dev/null +++ b/blackbox-test/src/test/java/org/example/customer/stream/MyArrayListTest.java @@ -0,0 +1,30 @@ +package org.example.customer.stream; + +import io.avaje.jsonb.Jsonb; +import org.junit.jupiter.api.Test; + +import java.util.ArrayList; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +class MyArrayListTest { + + Jsonb jsonb = Jsonb.builder().build(); + + @Test + void toJson_fromJson() { + MyArrayList myLinked = new MyArrayList(1, new ArrayList<>(List.of("a", "b", "c"))); + + String json = jsonb.toJson(myLinked); + assertNotNull(json); + assertThat(json).isEqualTo("{\"id\":1,\"names\":[\"a\",\"b\",\"c\"]}"); + + MyArrayList fromJson = jsonb.type(MyArrayList.class).fromJson(json); + assertEquals(myLinked, fromJson); + } +} diff --git a/blackbox-test/src/test/java/org/example/customer/stream/MyLinkedHashSetTest.java b/blackbox-test/src/test/java/org/example/customer/stream/MyLinkedHashSetTest.java new file mode 100644 index 00000000..965ccbbd --- /dev/null +++ b/blackbox-test/src/test/java/org/example/customer/stream/MyLinkedHashSetTest.java @@ -0,0 +1,28 @@ +package org.example.customer.stream; + +import io.avaje.jsonb.Jsonb; +import org.junit.jupiter.api.Test; + +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.*; + +class MyLinkedHashSetTest { + + Jsonb jsonb = Jsonb.builder().build(); + + @Test + void toJson_fromJson() { + MyLinked myLinked = new MyLinked(1, new LinkedHashSet<>(List.of("a", "b", "c"))); + + String json = jsonb.toJson(myLinked); + assertNotNull(json); + assertThat(json).isEqualTo("{\"id\":1,\"names\":[\"a\",\"b\",\"c\"]}"); + + MyLinked fromJson = jsonb.type(MyLinked.class).fromJson(json); + assertEquals(myLinked, fromJson); + } +}