From 6580b0185cb39bae755b46e3f5a4fd779166f504 Mon Sep 17 00:00:00 2001 From: huazhongming Date: Tue, 23 May 2023 21:02:21 +0800 Subject: [PATCH] Fix PojoUtils NPE problem (#12380) * Fix PojoUtils NPE problem Signed-off-by: crazyhzm * Fix code smell Signed-off-by: crazyhzm --------- Signed-off-by: crazyhzm --- .../apache/dubbo/common/utils/PojoUtils.java | 54 ++++++++++--------- 1 file changed, 29 insertions(+), 25 deletions(-) diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/utils/PojoUtils.java b/dubbo-common/src/main/java/org/apache/dubbo/common/utils/PojoUtils.java index 60a78061f4..30b454ebe8 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/utils/PojoUtils.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/utils/PojoUtils.java @@ -359,11 +359,11 @@ public class PojoUtils { Map mapGeneric = new HashMap<>(8); mapGeneric.putAll(mapParent); TypeVariable>[] typeParameters = type.getTypeParameters(); - if(genericType instanceof ParameterizedType && typeParameters.length > 0) { - ParameterizedType parameterizedType = (ParameterizedType)genericType; + if (genericType instanceof ParameterizedType && typeParameters.length > 0) { + ParameterizedType parameterizedType = (ParameterizedType) genericType; Type[] actualTypeArguments = parameterizedType.getActualTypeArguments(); for (int i = 0; i < typeParameters.length; i++) { - if(!(actualTypeArguments[i] instanceof TypeVariable)) { + if (!(actualTypeArguments[i] instanceof TypeVariable)) { mapGeneric.put(typeParameters[i].getTypeName(), actualTypeArguments[i]); } } @@ -534,26 +534,23 @@ public class PojoUtils { Object value = entry.getValue(); if (value != null) { Method method = getSetterMethod(dest.getClass(), name, value.getClass()); - Field field = getField(dest.getClass(), name); + Field field = getAndCacheField(dest.getClass(), name); if (method != null) { if (!method.isAccessible()) { method.setAccessible(true); } Type containType = mapGeneric.get(field.getGenericType().getTypeName()); - if(containType != null) { + if (containType != null) { //is generic - if(containType instanceof ParameterizedType) { - value = realize1(value, (Class) ((ParameterizedType)containType).getRawType(), containType, mapGeneric, history); - } - else if (containType instanceof Class){ + if (containType instanceof ParameterizedType) { + value = realize1(value, (Class) ((ParameterizedType) containType).getRawType(), containType, mapGeneric, history); + } else if (containType instanceof Class) { value = realize1(value, (Class) containType, containType, mapGeneric, history); - } - else { + } else { Type ptype = method.getGenericParameterTypes()[0]; value = realize1(value, method.getParameterTypes()[0], ptype, mapGeneric, history); } - } - else { + } else { Type ptype = method.getGenericParameterTypes()[0]; value = realize1(value, method.getParameterTypes()[0], ptype, mapGeneric, history); } @@ -626,7 +623,7 @@ public class PojoUtils { try { Constructor messagedConstructor = cls.getDeclaredConstructor(String.class); return messagedConstructor.newInstance(message); - } catch (Throwable t) { + } catch (Exception t) { return newInstance(cls); } } @@ -634,7 +631,7 @@ public class PojoUtils { private static Object newInstance(Class cls) { try { return cls.getDeclaredConstructor().newInstance(); - } catch (Throwable t) { + } catch (Exception t) { Constructor[] constructors = cls.getDeclaredConstructors(); /* From Javadoc java.lang.Class#getDeclaredConstructors @@ -653,7 +650,7 @@ public class PojoUtils { constructor.setAccessible(true); Object[] parameters = Arrays.stream(constructor.getParameterTypes()).map(PojoUtils::getDefaultValue).toArray(); return constructor.newInstance(parameters); - } catch (Throwable e) { + } catch (Exception e) { lastError = e; } } @@ -704,12 +701,24 @@ public class PojoUtils { return method; } - private static Field getField(Class cls, String fieldName) { - Field result = null; + private static Field getAndCacheField(Class cls, String fieldName) { + Field result; if (CLASS_FIELD_CACHE.containsKey(cls) && CLASS_FIELD_CACHE.get(cls).containsKey(fieldName)) { return CLASS_FIELD_CACHE.get(cls).get(fieldName); } - for(Class acls = cls; acls != null; acls = acls.getSuperclass()) { + + result = getField(cls, fieldName); + + if (result != null) { + ConcurrentMap fields = CLASS_FIELD_CACHE.computeIfAbsent(cls, k -> new ConcurrentHashMap<>()); + fields.putIfAbsent(fieldName, result); + } + return result; + } + + private static Field getField(Class cls, String fieldName) { + Field result = null; + for (Class acls = cls; acls != null; acls = acls.getSuperclass()) { try { result = acls.getDeclaredField(fieldName); if (!Modifier.isPublic(result.getModifiers())) { @@ -718,7 +727,7 @@ public class PojoUtils { } catch (NoSuchFieldException e) { } } - if(result == null) { + if (result == null && cls != null) { for (Field field : cls.getFields()) { if (fieldName.equals(field.getName()) && ReflectUtils.isPublicInstanceField(field)) { result = field; @@ -726,11 +735,6 @@ public class PojoUtils { } } } - - if (result != null) { - ConcurrentMap fields = CLASS_FIELD_CACHE.computeIfAbsent(cls, k -> new ConcurrentHashMap<>()); - fields.putIfAbsent(fieldName, result); - } return result; }