You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by co...@apache.org on 2026/10/14 05:31:32 UTC
(cxf) 01/01: CXF-8297 - Fix NPE in Aegis for generic array properties (e.g. T[])
This is an automated email from the ASF dual-hosted git repository.
coheigea pushed a commit to branch coheigea/CXF-8927
in repository https://gitbox.apache.org/repos/asf/cxf.git
commit e529d9637426f3952d57673215488b3655806700
Author: Colm O hEigeartaigh <co...@apache.org>
AuthorDate: Wed Oct 14 06:31:05 2026 +0100
CXF-8297 - Fix NPE in Aegis for generic array properties (e.g. T[])
---
.../java/org/apache/cxf/aegis/type/TypeUtil.java | 22 +++++++-
.../cxf/aegis/type/java5/GenericArrayTest.java | 66 ++++++++++++++++++++++
2 files changed, 87 insertions(+), 1 deletion(-)
diff --git a/rt/databinding/aegis/src/main/java/org/apache/cxf/aegis/type/TypeUtil.java b/rt/databinding/aegis/src/main/java/org/apache/cxf/aegis/type/TypeUtil.java
index 47842fb455c..86d3099ba9a 100644
--- a/rt/databinding/aegis/src/main/java/org/apache/cxf/aegis/type/TypeUtil.java
+++ b/rt/databinding/aegis/src/main/java/org/apache/cxf/aegis/type/TypeUtil.java
@@ -22,6 +22,8 @@ import java.lang.reflect.Array;
import java.lang.reflect.GenericArrayType;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
+import java.lang.reflect.TypeVariable;
+import java.lang.reflect.WildcardType;
import java.util.logging.Logger;
import javax.xml.namespace.QName;
@@ -251,7 +253,10 @@ public final class TypeUtil {
if (type instanceof GenericArrayType) {
GenericArrayType gat = (GenericArrayType) type;
Type compType = gat.getGenericComponentType();
- Class<?> arrayBaseType = getTypeRelatedClass(compType);
+ Class<?> arrayBaseType = getTypeRelatedClass(getErasedType(compType));
+ if (arrayBaseType == null) {
+ arrayBaseType = Object.class;
+ }
// believe it or not, this seems to be the only way to get the
// Class object for an array of primitive type.
Object instance = Array.newInstance(arrayBaseType, 0);
@@ -259,4 +264,19 @@ public final class TypeUtil {
}
return null;
}
+
+ /**
+ * Replace a type variable or wildcard by its (first) upper bound, e.g. so that
+ * the component type of a generic array such as T[] can be resolved to a class.
+ */
+ private static Type getErasedType(Type type) {
+ Type erased = type;
+ while (erased instanceof TypeVariable || erased instanceof WildcardType) {
+ Type[] bounds = erased instanceof TypeVariable
+ ? ((TypeVariable<?>) erased).getBounds()
+ : ((WildcardType) erased).getUpperBounds();
+ erased = bounds.length > 0 ? bounds[0] : Object.class;
+ }
+ return erased;
+ }
}
diff --git a/rt/databinding/aegis/src/test/java/org/apache/cxf/aegis/type/java5/GenericArrayTest.java b/rt/databinding/aegis/src/test/java/org/apache/cxf/aegis/type/java5/GenericArrayTest.java
new file mode 100644
index 00000000000..ef29ca33bdb
--- /dev/null
+++ b/rt/databinding/aegis/src/test/java/org/apache/cxf/aegis/type/java5/GenericArrayTest.java
@@ -0,0 +1,66 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cxf.aegis.type.java5;
+
+import org.w3c.dom.Document;
+
+import org.apache.cxf.aegis.AbstractAegisTest;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertNotNull;
+
+/**
+ * A bean property whose type is a generic array of a type variable (e.g. T[])
+ * used to cause a NullPointerException in TypeUtil.getTypeRelatedClass.
+ */
+public class GenericArrayTest extends AbstractAegisTest {
+
+ @Before
+ public void setUp() throws Exception {
+ super.setUp();
+ createService(GenericArrayService.class, "GenericArrayService");
+ }
+
+ @Test
+ public void testGenericArrayProperty() throws Exception {
+ Document doc = getWSDLDocument("GenericArrayService");
+ assertNotNull(doc);
+ assertValid("//xsd:complexType[@name='Page']", doc);
+ }
+
+ public static class Page<T> {
+ private T[] items;
+
+ public T[] getItems() {
+ return items;
+ }
+
+ public void setItems(T[] items) {
+ this.items = items;
+ }
+ }
+
+ public static class GenericArrayService {
+ public Page<String> getPage() {
+ return new Page<>();
+ }
+ }
+}