[599] Add better support for resolution of wildcard types.

Signed-off-by: James R. Perkins <jperkins@redhat.com>
diff --git a/src/main/java/org/eclipse/yasson/internal/ReflectionUtils.java b/src/main/java/org/eclipse/yasson/internal/ReflectionUtils.java
index 66ccac9..1c7cca1 100644
--- a/src/main/java/org/eclipse/yasson/internal/ReflectionUtils.java
+++ b/src/main/java/org/eclipse/yasson/internal/ReflectionUtils.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2023 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0 which is available at
@@ -190,6 +190,10 @@
             if (tmp != null) {
                 returnType = tmp;
             }
+            // If the type is a WildcardType we need to resolve the most specific type
+            if (returnType instanceof WildcardType) {
+                return resolveMostSpecificBound(chain, (WildcardType) returnType, warn);
+            }
             if (!(returnType instanceof TypeVariable)) {
                 break;
             }
diff --git a/src/main/java/org/eclipse/yasson/internal/deserializer/DeserializationModelCreator.java b/src/main/java/org/eclipse/yasson/internal/deserializer/DeserializationModelCreator.java
index 0ac3f98..1f1bdab 100644
--- a/src/main/java/org/eclipse/yasson/internal/deserializer/DeserializationModelCreator.java
+++ b/src/main/java/org/eclipse/yasson/internal/deserializer/DeserializationModelCreator.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021, 2023 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2021 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0 which is available at
@@ -233,7 +233,7 @@
             if (creatorModel.getCustomization().isRequired()) {
                 defaultCreatorValues.put(parameterName, new RequiredCreatorParameter(parameterName));
             } else {
-                Class<?> rawParamType = ReflectionUtils.getRawType(creatorModel.getType());
+                Class<?> rawParamType = ReflectionUtils.getOptionalRawType(creatorModel.getType()).orElse(Object.class);
                 defaultCreatorValues.put(parameterName, DEFAULT_CREATOR_VALUES.getOrDefault(rawParamType, NULL_PROVIDER));
             }
         }
diff --git a/src/test/java/org/eclipse/yasson/defaultmapping/generics/GenericsTest.java b/src/test/java/org/eclipse/yasson/defaultmapping/generics/GenericsTest.java
index a1bf7f2..1362361 100644
--- a/src/test/java/org/eclipse/yasson/defaultmapping/generics/GenericsTest.java
+++ b/src/test/java/org/eclipse/yasson/defaultmapping/generics/GenericsTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2023 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0 which is available at
@@ -13,6 +13,7 @@
 package org.eclipse.yasson.defaultmapping.generics;
 
 import java.lang.reflect.Type;
+import java.lang.reflect.WildcardType;
 import java.math.BigDecimal;
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
@@ -36,8 +37,11 @@
 import org.eclipse.yasson.defaultmapping.generics.model.AnotherGenericTestClass;
 import org.eclipse.yasson.defaultmapping.generics.model.BoundedGenericClass;
 import org.eclipse.yasson.defaultmapping.generics.model.Circle;
+import org.eclipse.yasson.defaultmapping.generics.model.CollectionContainer;
+import org.eclipse.yasson.defaultmapping.generics.model.CollectionElement;
 import org.eclipse.yasson.defaultmapping.generics.model.CollectionWrapper;
 import org.eclipse.yasson.defaultmapping.generics.model.ColoredCircle;
+import org.eclipse.yasson.defaultmapping.generics.model.ConstructorContainer;
 import org.eclipse.yasson.defaultmapping.generics.model.CyclicSubClass;
 import org.eclipse.yasson.defaultmapping.generics.model.FinalGenericWrapper;
 import org.eclipse.yasson.defaultmapping.generics.model.FinalMember;
@@ -49,6 +53,7 @@
 import org.eclipse.yasson.defaultmapping.generics.model.MyCyclicGenericClass;
 import org.eclipse.yasson.defaultmapping.generics.model.PropagatedGenericClass;
 import org.eclipse.yasson.defaultmapping.generics.model.Shape;
+import org.eclipse.yasson.defaultmapping.generics.model.StaticCreatorContainer;
 import org.eclipse.yasson.defaultmapping.generics.model.WildCardClass;
 import org.eclipse.yasson.defaultmapping.generics.model.WildcardMultipleBoundsClass;
 import org.eclipse.yasson.serializers.model.Box;
@@ -474,6 +479,40 @@
         assertEquals(6, fromJson.get(0).field1);
         
     }
+
+    @Test
+    public void genericConstructorCreator() {
+        final String expectedJson = "{\"value\":\"Test\"}";
+        final ConstructorContainer<String> container = new ConstructorContainer<>("Test");
+
+        assertEquals(expectedJson, defaultJsonb.toJson(container));
+        assertEquals(container, defaultJsonb.fromJson(expectedJson, ConstructorContainer.class));
+    }
+
+    @Test
+    public void genericStaticCreator() {
+        final String expectedJson = "{\"value\":\"static\"}";
+        final StaticCreatorContainer<String> container = StaticCreatorContainer.create("static");
+
+        assertEquals(expectedJson, defaultJsonb.toJson(container));
+        assertEquals(container, defaultJsonb.fromJson(expectedJson, StaticCreatorContainer.class));
+    }
+
+    @Test
+    public void wildcardCollectionContainer() {
+        final String expectedJson = "{\"collection\":{\"collection\":[{\"wrapped\":\"wrappedElement\"}]}}";
+        final CollectionContainer collectionContainer = new CollectionContainer();
+        final CollectionWrapper<CollectionElement<?>> collectionWrapper = new CollectionWrapper<>();
+        final CollectionElement<String> wildcardType = new CollectionElement<>();
+        wildcardType.setWrapped("wrappedElement");
+        final Collection<CollectionElement<?>> list = List.of(wildcardType);
+        collectionWrapper.setCollection(list);
+        collectionContainer.setCollection(collectionWrapper);
+
+        assertEquals(expectedJson, defaultJsonb.toJson(collectionContainer));
+        final CollectionContainer result = defaultJsonb.fromJson(expectedJson, CollectionContainer.class);
+        assertEquals(collectionContainer, result);
+    }
     
     public interface FunctionalInterface<T> {
         T getValue();
diff --git a/src/test/java/org/eclipse/yasson/defaultmapping/generics/model/CollectionContainer.java b/src/test/java/org/eclipse/yasson/defaultmapping/generics/model/CollectionContainer.java
new file mode 100644
index 0000000..4ef94d0
--- /dev/null
+++ b/src/test/java/org/eclipse/yasson/defaultmapping/generics/model/CollectionContainer.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2025 Red Hat, Inc. and/or its affiliates.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+
+package org.eclipse.yasson.defaultmapping.generics.model;
+
+import java.util.Collection;
+import java.util.Objects;
+
+/**
+ * @author <a href="mailto:jperkins@redhat.com">James R. Perkins</a>
+ */
+public class CollectionContainer {
+
+    private CollectionWrapper<CollectionElement<?>> collection;
+
+    public CollectionWrapper<CollectionElement<?>> getCollection() {
+        return collection;
+    }
+
+    public void setCollection(final CollectionWrapper<CollectionElement<?>> collection) {
+        this.collection = collection;
+    }
+
+    @Override
+    public boolean equals(final Object obj) {
+        if (obj == this) {
+            return true;
+        }
+        if (!(obj instanceof CollectionContainer)) {
+            return false;
+        }
+        final CollectionContainer other = (CollectionContainer) obj;
+        final Collection<CollectionElement<?>> thisCollection = collection.getCollection();
+        final Collection<CollectionElement<?>> otherCollection = other.collection.getCollection();
+        if (thisCollection == null && otherCollection == null) {
+            return true;
+        }
+        if (thisCollection == null || otherCollection == null) {
+            return false;
+        }
+        return thisCollection.containsAll(otherCollection) && otherCollection.containsAll(thisCollection);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(collection);
+    }
+}
diff --git a/src/test/java/org/eclipse/yasson/defaultmapping/generics/model/CollectionElement.java b/src/test/java/org/eclipse/yasson/defaultmapping/generics/model/CollectionElement.java
new file mode 100644
index 0000000..2791dfc
--- /dev/null
+++ b/src/test/java/org/eclipse/yasson/defaultmapping/generics/model/CollectionElement.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2025 Red Hat, Inc. and/or its affiliates.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+
+package org.eclipse.yasson.defaultmapping.generics.model;
+
+import java.util.Objects;
+
+/**
+ * @author <a href="mailto:jperkins@redhat.com">James R. Perkins</a>
+ */
+public class CollectionElement<T> {
+
+    private T wrapped;
+
+    public T getWrapped() {
+        return wrapped;
+    }
+
+    public void setWrapped(T wrapped) {
+        this.wrapped = wrapped;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(wrapped);
+    }
+
+    @Override
+    public boolean equals(final Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (!(obj instanceof CollectionElement)) {
+            return false;
+        }
+        final CollectionElement<?> other = (CollectionElement<?>) obj;
+        return Objects.equals(wrapped, other.wrapped);
+    }
+}
diff --git a/src/test/java/org/eclipse/yasson/defaultmapping/generics/model/ConstructorContainer.java b/src/test/java/org/eclipse/yasson/defaultmapping/generics/model/ConstructorContainer.java
new file mode 100644
index 0000000..d2da4a2
--- /dev/null
+++ b/src/test/java/org/eclipse/yasson/defaultmapping/generics/model/ConstructorContainer.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2025 Red Hat, Inc. and/or its affiliates.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+
+package org.eclipse.yasson.defaultmapping.generics.model;
+
+import java.util.Objects;
+
+import jakarta.json.bind.annotation.JsonbCreator;
+import jakarta.json.bind.annotation.JsonbProperty;
+
+/**
+ * @author <a href="mailto:jperkins@redhat.com">James R. Perkins</a>
+ */
+public class ConstructorContainer<T> {
+
+    private final T value;
+
+    @JsonbCreator
+    public ConstructorContainer(@JsonbProperty("value") final T value) {
+        this.value = value;
+    }
+
+    public T getValue() {
+        return value;
+    }
+
+    @Override
+    public String toString() {
+        return "ConstructorContainer[value=" + value + "]";
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(value);
+    }
+
+    @Override
+    public boolean equals(final Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (!(obj instanceof ConstructorContainer)) {
+            return false;
+        }
+        final ConstructorContainer<?> other = (ConstructorContainer<?>) obj;
+        return Objects.equals(value, other.value);
+    }
+}
diff --git a/src/test/java/org/eclipse/yasson/defaultmapping/generics/model/StaticCreatorContainer.java b/src/test/java/org/eclipse/yasson/defaultmapping/generics/model/StaticCreatorContainer.java
new file mode 100644
index 0000000..c090c5f
--- /dev/null
+++ b/src/test/java/org/eclipse/yasson/defaultmapping/generics/model/StaticCreatorContainer.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2025 Red Hat, Inc. and/or its affiliates.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+
+package org.eclipse.yasson.defaultmapping.generics.model;
+
+import java.util.Objects;
+
+import jakarta.json.bind.annotation.JsonbCreator;
+import jakarta.json.bind.annotation.JsonbProperty;
+
+/**
+ * @author <a href="mailto:jperkins@redhat.com">James R. Perkins</a>
+ */
+public class StaticCreatorContainer<T> {
+    private final T value;
+
+    private StaticCreatorContainer(T value) {
+        this.value = value;
+    }
+
+    @JsonbCreator
+    public static <T> StaticCreatorContainer<T> create(@JsonbProperty("value") final T value) {
+        return new StaticCreatorContainer<>(value);
+    }
+
+    public T getValue() {
+        return value;
+    }
+
+    @Override
+    public String toString() {
+        return "StaticCreatorContainer[value=" + value + "]";
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(value);
+    }
+
+    @Override
+    public boolean equals(final Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (!(obj instanceof StaticCreatorContainer)) {
+            return false;
+        }
+        final StaticCreatorContainer<?> other = (StaticCreatorContainer<?>) obj;
+        return Objects.equals(value, other.value);
+    }
+
+}