Author: niallp
Date: Fri Sep 10 12:19:08 2010
New Revision: 995768

URL: http://svn.apache.org/viewvc?rev=995768&view=rev
Log:
BEANUTILS-380 BeanMap methods should initialize the root cause of exceptions 
that are thrown when running on JDK 1.4+ - thanks to Brendan Nolan

Modified:
    commons/proper/beanutils/trunk/src/changes/changes.xml
    
commons/proper/beanutils/trunk/src/main/java/org/apache/commons/beanutils/BeanMap.java
    
commons/proper/beanutils/trunk/src/test/java/org/apache/commons/beanutils/BeanMapTestCase.java
    
commons/proper/beanutils/trunk/src/test/java/org/apache/commons/beanutils/BeanUtilsTestCase.java

Modified: commons/proper/beanutils/trunk/src/changes/changes.xml
URL: 
http://svn.apache.org/viewvc/commons/proper/beanutils/trunk/src/changes/changes.xml?rev=995768&r1=995767&r2=995768&view=diff
==============================================================================
--- commons/proper/beanutils/trunk/src/changes/changes.xml (original)
+++ commons/proper/beanutils/trunk/src/changes/changes.xml Fri Sep 10 12:19:08 
2010
@@ -39,6 +39,13 @@ The <action> type attribute can be add,u
   </properties>
   <body>
 
+    <release version="1.8.4" date="in SVN" description="Bug fix for 1.8.3">
+      <action dev="niallp" type="fix" issue="BEANUTILS-380" due-to="Brendan 
Nolan">
+         BeanMap methods should initialize the root cause of exceptions that 
are thrown
+         when running on JDK 1.4+
+      </action>
+    </release>
+
     <release version="1.8.3" date="2010-03-28" description="Bug fix for 1.8.2">
       <action dev="niallp" type="fix" issue="BEANUTILS-373" due-to="Andrew 
Sunde">
          MethodUtils is not thread safe because WeakFastHashMap which uses 
WeakHashMap is not thread-safe

Modified: 
commons/proper/beanutils/trunk/src/main/java/org/apache/commons/beanutils/BeanMap.java
URL: 
http://svn.apache.org/viewvc/commons/proper/beanutils/trunk/src/main/java/org/apache/commons/beanutils/BeanMap.java?rev=995768&r1=995767&r2=995768&view=diff
==============================================================================
--- 
commons/proper/beanutils/trunk/src/main/java/org/apache/commons/beanutils/BeanMap.java
 (original)
+++ 
commons/proper/beanutils/trunk/src/main/java/org/apache/commons/beanutils/BeanMap.java
 Fri Sep 10 12:19:08 2010
@@ -261,17 +261,21 @@ public class BeanMap extends AbstractMap
             newBean = beanClass.newInstance();
         } catch (Exception e) {
             // unable to instantiate
-            throw new CloneNotSupportedException
+            CloneNotSupportedException cnse = new CloneNotSupportedException
                 ("Unable to instantiate the underlying bean \"" +
                  beanClass.getName() + "\": " + e);
+            BeanUtils.initCause(cnse, e);
+            throw cnse;
         }
             
         try {
             newMap.setBean(newBean);
         } catch (Exception exception) {
-            throw new CloneNotSupportedException
+            CloneNotSupportedException cnse = new CloneNotSupportedException
                 ("Unable to set bean in the cloned bean map: " + 
                  exception);
+            BeanUtils.initCause(cnse, exception);
+            throw cnse;
         }
             
         try {
@@ -286,9 +290,11 @@ public class BeanMap extends AbstractMap
                 }
             }
         } catch (Exception exception) {
-            throw new CloneNotSupportedException
+            CloneNotSupportedException cnse = new CloneNotSupportedException
                 ("Unable to copy bean values to cloned bean map: " +
                  exception);
+            BeanUtils.initCause(cnse, exception);
+            throw cnse;
         }
 
         return newMap;
@@ -330,7 +336,10 @@ public class BeanMap extends AbstractMap
             bean = beanClass.newInstance();
         }
         catch (Exception e) {
-            throw new UnsupportedOperationException( "Could not create new 
instance of class: " + beanClass );
+            UnsupportedOperationException uoe =
+                new UnsupportedOperationException("Could not create new 
instance of class: " + beanClass);
+            BeanUtils.initCause(uoe, e);
+            throw uoe;
         }
     }
 
@@ -434,12 +443,18 @@ public class BeanMap extends AbstractMap
                 firePropertyChange( name, oldValue, newValue );
             }
             catch ( InvocationTargetException e ) {
-                logInfo( e );
-                throw new IllegalArgumentException( e.getMessage() );
+                IllegalArgumentException iae = new 
IllegalArgumentException(e.getMessage());
+                if (BeanUtils.initCause(iae, e) == false) {
+                    logInfo(e);
+                }
+                throw iae;
             }
             catch ( IllegalAccessException e ) {
-                logInfo( e );
-                throw new IllegalArgumentException( e.getMessage() );
+                IllegalArgumentException iae = new 
IllegalArgumentException(e.getMessage());
+                if (BeanUtils.initCause(iae, e) == false) {
+                    logInfo(e);
+                }
+                throw iae;
             }
             return oldValue;
         }
@@ -771,12 +786,19 @@ public class BeanMap extends AbstractMap
             return answer;
         }
         catch ( InvocationTargetException e ) {
-            logInfo( e );
-            throw new IllegalArgumentException( e.getMessage() );
+            IllegalArgumentException iae = new 
IllegalArgumentException(e.getMessage());
+            if (BeanUtils.initCause(iae, e) == false) {
+                logInfo(e);
+            }
+            throw iae;
         }
         catch ( InstantiationException e ) {
-            logInfo( e );
-            throw new IllegalArgumentException( e.getMessage() );
+            IllegalArgumentException iae = new 
IllegalArgumentException(e.getMessage());
+            if (BeanUtils.initCause(iae, e) == false) {
+                logInfo(e);
+            }
+            BeanUtils.initCause(iae, e);
+            throw iae;
         }
     }
 

Modified: 
commons/proper/beanutils/trunk/src/test/java/org/apache/commons/beanutils/BeanMapTestCase.java
URL: 
http://svn.apache.org/viewvc/commons/proper/beanutils/trunk/src/test/java/org/apache/commons/beanutils/BeanMapTestCase.java?rev=995768&r1=995767&r2=995768&view=diff
==============================================================================
--- 
commons/proper/beanutils/trunk/src/test/java/org/apache/commons/beanutils/BeanMapTestCase.java
 (original)
+++ 
commons/proper/beanutils/trunk/src/test/java/org/apache/commons/beanutils/BeanMapTestCase.java
 Fri Sep 10 12:19:08 2010
@@ -17,6 +17,7 @@
 package org.apache.commons.beanutils;
 
 import java.io.Serializable;
+import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.util.Map;
 import java.util.HashMap;
@@ -24,6 +25,7 @@ import java.util.HashMap;
 import junit.framework.Test;
 import junit.textui.TestRunner;
 
+import org.apache.commons.beanutils.bugs.other.Jira87BeanFactory;
 import org.apache.commons.collections.map.AbstractTestMap;
 import org.apache.commons.collections.BulkTest;
 import org.apache.commons.collections.Transformer;
@@ -151,6 +153,23 @@ public class BeanMapTestCase extends Abs
             someObject = value;
         }
     }
+
+    public static class BeanThrowingExceptions extends BeanWithProperties {
+        private static final long serialVersionUID = 1L;
+        public void setValueThrowingException(String value) {
+            throw new TestException();
+        }
+        public String getValueThrowingException() {
+            throw new TestException();
+        }
+    }
+
+    /**
+     * Exception for testing exception handling.
+     */
+    public static class TestException extends RuntimeException {
+        private static final long serialVersionUID = 1L;
+    }
     
     // note to self.  The Sample keys were generated by copying the field
     // declarations and using the following regular expression search and 
replace:
@@ -413,5 +432,105 @@ public class BeanMapTestCase extends Abs
             // expected result
         }
     }
-   
+
+    /**
+     * Test that the cause of exception thrown by a clone() is initialised.
+     */
+    public void testExceptionThrowFromClone() {
+
+        if (BeanUtilsTestCase.isPre14JVM()) {
+            System.out.println("testExceptionThrowFromClone() skipped on pre 
1.4 JVM");
+            return;
+        }
+
+        // Test cloning a non-public bean (instantiation exception)
+        try {
+            Object bean = Jira87BeanFactory.createMappedPropertyBean();
+            BeanMap map = new BeanMap(bean);
+            map.clone();
+            fail("Non-public bean clone() - expected 
CloneNotSupportedException");
+        } catch (CloneNotSupportedException e) {
+            Throwable cause = null;
+            try {
+                cause = (Throwable)PropertyUtils.getProperty(e, "cause");
+            } catch (Exception e2) {
+                fail("Non-public bean - retrieving the cause threw " + e2);
+            }
+            assertNotNull("Non-public bean cause null", cause);
+            assertEquals("Non-public bean cause", 
IllegalAccessException.class, cause.getClass());
+        }
+
+        // Test cloning a bean that throws exception
+        try {
+            BeanMap map = new BeanMap(new BeanThrowingExceptions());
+            map.clone();
+            fail("Setter Exception clone() - expected 
CloneNotSupportedException");
+        } catch (CloneNotSupportedException e) {
+            Throwable cause = null;
+            try {
+                cause = (Throwable)PropertyUtils.getProperty(e, "cause");
+            } catch (Exception e2) {
+                fail("Setter Exception - retrieving the cause threw " + e2);
+            }
+            assertNotNull("Setter Exception cause null", cause);
+            assertEquals("Setter Exception cause", 
IllegalArgumentException.class, cause.getClass());
+        }
+    }
+
+    /**
+     * Test that the cause of exception thrown by clear() is initialised.
+     */
+    public void testExceptionThrowFromClear() {
+
+        if (BeanUtilsTestCase.isPre14JVM()) {
+            System.out.println("testExceptionThrowFromClear() skipped on pre 
1.4 JVM");
+            return;
+        }
+
+        try {
+            Object bean = Jira87BeanFactory.createMappedPropertyBean();
+            BeanMap map = new BeanMap(bean);
+            map.clear();
+            fail("clear() - expected UnsupportedOperationException");
+        } catch (UnsupportedOperationException e) {
+            Throwable cause = null;
+            try {
+                cause = (Throwable)PropertyUtils.getProperty(e, "cause");
+            } catch (Exception e2) {
+                fail("Retrieving the cause threw " + e2);
+            }
+            assertNotNull("Cause null", cause);
+            assertEquals("Cause", IllegalAccessException.class, 
cause.getClass());
+        }
+    }
+
+    /**
+     * Test that the cause of exception thrown by put() is initialised.
+     */
+    public void testExceptionThrowFromPut() {
+
+        if (BeanUtilsTestCase.isPre14JVM()) {
+            System.out.println("testExceptionThrowFromPut() skipped on pre 1.4 
JVM");
+            return;
+        }
+
+        try {
+            Map map = new BeanMap(new BeanThrowingExceptions());
+            map.put("valueThrowingException", "value");
+            fail("Setter exception - expected IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            Throwable cause1 = null;
+            Throwable cause2 = null;
+            try {
+                cause1 = (Throwable)PropertyUtils.getProperty(e, "cause");
+                cause2 = (Throwable)PropertyUtils.getProperty(e, 
"cause.cause");
+            } catch (Exception e2) {
+                fail("Setter exception - retrieving the cause threw " + e2);
+            }
+            assertNotNull("Setter exception cause 1 null", cause1);
+            assertEquals("Setter exception cause 1", 
InvocationTargetException.class, cause1.getClass());
+            assertNotNull("Setter exception cause 2 null", cause2);
+            assertEquals("Setter exception cause 2", TestException.class, 
cause2.getClass());
+        }
+    }
 }

Modified: 
commons/proper/beanutils/trunk/src/test/java/org/apache/commons/beanutils/BeanUtilsTestCase.java
URL: 
http://svn.apache.org/viewvc/commons/proper/beanutils/trunk/src/test/java/org/apache/commons/beanutils/BeanUtilsTestCase.java?rev=995768&r1=995767&r2=995768&view=diff
==============================================================================
--- 
commons/proper/beanutils/trunk/src/test/java/org/apache/commons/beanutils/BeanUtilsTestCase.java
 (original)
+++ 
commons/proper/beanutils/trunk/src/test/java/org/apache/commons/beanutils/BeanUtilsTestCase.java
 Fri Sep 10 12:19:08 2010
@@ -1645,7 +1645,7 @@ public class BeanUtilsTestCase extends T
     /**
      * Test for JDK 1.4
      */
-    private boolean isPre14JVM() {
+    public static boolean isPre14JVM() {
         String version = System.getProperty("java.specification.version");
         StringTokenizer tokenizer = new StringTokenizer(version,".");
         if (tokenizer.nextToken().equals("1")) {


Reply via email to