Author: bimargulies
Date: Tue Sep 8 18:36:56 2009
New Revision: 812615
URL: http://svn.apache.org/viewvc?rev=812615&view=rev
Log:
CXF-2417. Borrow help from Spring to avoid leaks and other problems with
property descriptors.
Non-spring users are stuck with Sun's bugs for now.
Modified:
cxf/trunk/common/common/src/main/java/org/apache/cxf/common/util/ReflectionUtil.java
cxf/trunk/rt/databinding/aegis/src/main/java/org/apache/cxf/aegis/type/basic/BeanTypeInfo.java
Modified:
cxf/trunk/common/common/src/main/java/org/apache/cxf/common/util/ReflectionUtil.java
URL:
http://svn.apache.org/viewvc/cxf/trunk/common/common/src/main/java/org/apache/cxf/common/util/ReflectionUtil.java?rev=812615&r1=812614&r2=812615&view=diff
==============================================================================
---
cxf/trunk/common/common/src/main/java/org/apache/cxf/common/util/ReflectionUtil.java
(original)
+++
cxf/trunk/common/common/src/main/java/org/apache/cxf/common/util/ReflectionUtil.java
Tue Sep 8 18:36:56 2009
@@ -19,12 +19,22 @@
package org.apache.cxf.common.util;
+import java.beans.BeanInfo;
+import java.beans.PropertyDescriptor;
import java.io.File;
import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
import java.net.*;
import java.util.*;
+import org.apache.cxf.common.classloader.ClassLoaderUtils;
+
public final class ReflectionUtil {
+
+ private static Method springBeanUtilsDescriptorFetcher;
+ private static boolean springChecked;
+
private ReflectionUtil() {
// intentionally empty
}
@@ -79,4 +89,62 @@
String packageName = clzName.substring(0, clzName.lastIndexOf("/"));
return packageName.replace("/", ".");
}
+
+ /**
+ * create own array of property descriptors to:
+ * <pre>
+ * - prevent memory leaks by Introspector's cache
+ * - get correct type for generic properties from superclass
+ * that are limited to a specific type in beanClass
+ * see http://bugs.sun.com/view_bug.do?bug_id=6528714
+ * we cannot use BeanUtils.getPropertyDescriptors because of issue
SPR-6063
+ * </pre>
+ * @param refClass calling class for class loading.
+ * @param beanInfo Bean in question
+ * @param beanClass class for bean in question
+ * @param propertyDescriptors raw descriptors
+ * @return
+ */
+ public static PropertyDescriptor[]
getPropertyDescriptorsAvoidSunBug(Class<?> refClass,
+ BeanInfo
beanInfo,
+ Class<?>
beanClass,
+
PropertyDescriptor[] propertyDescriptors) {
+ if (!springChecked) {
+ try {
+ springChecked = true;
+ Class<?> cls = ClassLoaderUtils
+ .loadClass("org.springframework.beans.BeanUtils",
refClass);
+ springBeanUtilsDescriptorFetcher
+ = cls.getMethod("getPropertyDescriptor", new Class[]
{Class.class, String.class});
+ } catch (Exception e) {
+ //ignore - just assume it's an unsupported/unknown annotation
+ }
+ }
+
+ if (springBeanUtilsDescriptorFetcher != null) {
+ PropertyDescriptor[] descriptors = null;
+ if (propertyDescriptors != null) {
+ descriptors = new
PropertyDescriptor[propertyDescriptors.length];
+ for (int i = 0; i < propertyDescriptors.length; i++) {
+ PropertyDescriptor propertyDescriptor =
propertyDescriptors[i];
+ try {
+ descriptors[i] =
+ (PropertyDescriptor)
+ springBeanUtilsDescriptorFetcher.invoke(null,
+ beanClass,
+
propertyDescriptor.getName());
+ } catch (IllegalArgumentException e) {
+ throw new RuntimeException(e);
+ } catch (IllegalAccessException e) {
+ throw new RuntimeException(e);
+ } catch (InvocationTargetException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+ return descriptors;
+ } else {
+ return beanInfo.getPropertyDescriptors();
+ }
+ }
}
Modified:
cxf/trunk/rt/databinding/aegis/src/main/java/org/apache/cxf/aegis/type/basic/BeanTypeInfo.java
URL:
http://svn.apache.org/viewvc/cxf/trunk/rt/databinding/aegis/src/main/java/org/apache/cxf/aegis/type/basic/BeanTypeInfo.java?rev=812615&r1=812614&r2=812615&view=diff
==============================================================================
---
cxf/trunk/rt/databinding/aegis/src/main/java/org/apache/cxf/aegis/type/basic/BeanTypeInfo.java
(original)
+++
cxf/trunk/rt/databinding/aegis/src/main/java/org/apache/cxf/aegis/type/basic/BeanTypeInfo.java
Tue Sep 8 18:36:56 2009
@@ -36,6 +36,7 @@
import org.apache.cxf.aegis.type.AegisType;
import org.apache.cxf.aegis.type.TypeCreator;
import org.apache.cxf.aegis.type.TypeMapping;
+import org.apache.cxf.common.util.ReflectionUtil;
public class BeanTypeInfo {
private Map<QName, QName> mappedName2typeName = new HashMap<QName,
QName>();
@@ -286,7 +287,14 @@
}
if (beanInfo != null) {
- descriptors = beanInfo.getPropertyDescriptors();
+ PropertyDescriptor[] propertyDescriptors =
beanInfo.getPropertyDescriptors();
+ if (propertyDescriptors != null) {
+ // see comments on this function.
+ descriptors =
ReflectionUtil.getPropertyDescriptorsAvoidSunBug(getClass(),
+
beanInfo,
+
beanClass,
+
propertyDescriptors);
+ }
}
if (descriptors == null) {