Author: niallp
Date: Thu Aug 28 07:12:13 2008
New Revision: 689831
URL: http://svn.apache.org/viewvc?rev=689831&view=rev
Log:
BEANUTILS-291 - Re-create class reference if lost - fixes problem on JRockit
JDK - thanks to Jörg Schaible
Modified:
commons/proper/beanutils/trunk/src/java/org/apache/commons/beanutils/MappedPropertyDescriptor.java
commons/proper/beanutils/trunk/src/test/org/apache/commons/beanutils/memoryleaktests/MemoryLeakTestCase.java
Modified:
commons/proper/beanutils/trunk/src/java/org/apache/commons/beanutils/MappedPropertyDescriptor.java
URL:
http://svn.apache.org/viewvc/commons/proper/beanutils/trunk/src/java/org/apache/commons/beanutils/MappedPropertyDescriptor.java?rev=689831&r1=689830&r2=689831&view=diff
==============================================================================
---
commons/proper/beanutils/trunk/src/java/org/apache/commons/beanutils/MappedPropertyDescriptor.java
(original)
+++
commons/proper/beanutils/trunk/src/java/org/apache/commons/beanutils/MappedPropertyDescriptor.java
Thu Aug 28 07:12:13 2008
@@ -452,6 +452,12 @@
if (m == null) {
Class clazz = (Class)classRef.get();
if (clazz == null) {
+ clazz = reLoadClass();
+ if (clazz != null) {
+ classRef = new WeakReference(clazz);
+ }
+ }
+ if (clazz == null) {
throw new RuntimeException("Method " + methodName + " for
" +
className + " could not be reconstructed - class
reference has gone");
}
@@ -473,5 +479,29 @@
}
return m;
}
+
+ /**
+ * Try to re-load the class
+ */
+ private Class reLoadClass() {
+
+ ClassLoader classLoader =
Thread.currentThread().getContextClassLoader();
+
+ // Try the context class loader
+ if (classLoader != null) {
+ try {
+ return classLoader.loadClass(className);
+ } catch (Throwable t) {
+ // ignore
+ }
+ }
+
+ // Try this class's class loader
+ try {
+ return classLoader.loadClass(className);
+ } catch (Throwable t) {
+ return null;
+ }
+ }
}
}
Modified:
commons/proper/beanutils/trunk/src/test/org/apache/commons/beanutils/memoryleaktests/MemoryLeakTestCase.java
URL:
http://svn.apache.org/viewvc/commons/proper/beanutils/trunk/src/test/org/apache/commons/beanutils/memoryleaktests/MemoryLeakTestCase.java?rev=689831&r1=689830&r2=689831&view=diff
==============================================================================
---
commons/proper/beanutils/trunk/src/test/org/apache/commons/beanutils/memoryleaktests/MemoryLeakTestCase.java
(original)
+++
commons/proper/beanutils/trunk/src/test/org/apache/commons/beanutils/memoryleaktests/MemoryLeakTestCase.java
Thu Aug 28 07:12:13 2008
@@ -155,7 +155,7 @@
* Tests that MappedPropertyDescriptor can re-create the Method reference
after it
* has been garbage collected.
*/
- public void testMappedPropertyDescriptor_MappedMethodReference() throws
Exception {
+ public void testMappedPropertyDescriptor_MappedMethodReference1() throws
Exception {
// Clear All BeanUtils caches before the test
clearAllBeanUtilsCaches();
@@ -196,6 +196,55 @@
}
/**
+ * Tests that MappedPropertyDescriptor can re-create the Method reference
after it
+ * has been garbage collected.
+ */
+ public void testMappedPropertyDescriptor_MappedMethodReference2() throws
Exception {
+
+ // Clear All BeanUtils caches before the test
+ clearAllBeanUtilsCaches();
+
+ String className =
"org.apache.commons.beanutils.memoryleaktests.pojotests.SomeMappedPojo";
+ ClassLoader loader = newClassLoader();
+ Class beanClass = loader.loadClass(className);
+ Object bean = beanClass.newInstance();
+ //
-----------------------------------------------------------------------------
+
+ // Sanity checks only
+ assertNotNull("ClassLoader is null", loader);
+ assertNotNull("BeanClass is null", beanClass);
+ assertNotSame("ClassLoaders should be different..",
getClass().getClassLoader(), beanClass.getClassLoader());
+ assertSame("BeanClass ClassLoader incorrect",
beanClass.getClassLoader(), loader);
+
+ MappedPropertyDescriptor descriptor = new
MappedPropertyDescriptor("mappedProperty", beanClass);
+ assertNotNull("1-Read Method null", descriptor.getMappedReadMethod());
+ assertNotNull("1-Write Method null",
descriptor.getMappedWriteMethod());
+ assertEquals("1-Read Method name", "getMappedProperty",
descriptor.getMappedReadMethod().getName());
+ assertEquals("1-Read Write name", "setMappedProperty",
descriptor.getMappedWriteMethod().getName());
+
+ // this should make the reference go away.
+ loader = null;
+ beanClass = null;
+ bean = null;
+
+ forceGarbageCollection(); /* Try to force the garbage collector to run
by filling up memory */
+
+ // The aim of this test is to check the functinality in
MappedPropertyDescriptor which
+ // re-creates the Method references after they have been garbage
collected. However theres no
+ // way of knowing the method references were garbage collected and
that code was run, except by
+ // un-commeting the System.out statement in MappedPropertyDescriptor's
MappedMethodReference's
+ // get() method.
+
+ assertNotNull("1-Read Method null", descriptor.getMappedReadMethod());
+ assertNotNull("1-Write Method null",
descriptor.getMappedWriteMethod());
+ assertEquals("1-Read Method name", "getMappedProperty",
descriptor.getMappedReadMethod().getName());
+ assertEquals("1-Read Write name", "setMappedProperty",
descriptor.getMappedWriteMethod().getName());
+
+ // Clear All BeanUtils caches after the test
+ clearAllBeanUtilsCaches();
+ }
+
+ /**
* Tests that MethodUtils's cache doesn't cause a memory leak.
*/
public void testMethodUtils_cache_memoryLeak() throws Exception {