You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by gg...@apache.org on 2006/01/05 18:35:48 UTC

svn commit: r366225 - in /jakarta/commons/proper/lang/trunk/src: java/org/apache/commons/lang/exception/ExceptionUtils.java test/org/apache/commons/lang/exception/ExceptionUtilsTestCase.java

Author: ggregory
Date: Thu Jan  5 09:35:43 2006
New Revision: 366225

URL: http://svn.apache.org/viewcvs?rev=366225&view=rev
Log:
http://issues.apache.org/bugzilla/show_bug.cgi?id=37574
[lang] [PATCH] new ExceptionUtils.setCause() method

Modified:
    jakarta/commons/proper/lang/trunk/src/java/org/apache/commons/lang/exception/ExceptionUtils.java
    jakarta/commons/proper/lang/trunk/src/test/org/apache/commons/lang/exception/ExceptionUtilsTestCase.java

Modified: jakarta/commons/proper/lang/trunk/src/java/org/apache/commons/lang/exception/ExceptionUtils.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/lang/trunk/src/java/org/apache/commons/lang/exception/ExceptionUtils.java?rev=366225&r1=366224&r2=366225&view=diff
==============================================================================
--- jakarta/commons/proper/lang/trunk/src/java/org/apache/commons/lang/exception/ExceptionUtils.java (original)
+++ jakarta/commons/proper/lang/trunk/src/java/org/apache/commons/lang/exception/ExceptionUtils.java Thu Jan  5 09:35:43 2006
@@ -31,10 +31,11 @@
 import org.apache.commons.lang.ArrayUtils;
 import org.apache.commons.lang.StringUtils;
 import org.apache.commons.lang.SystemUtils;
+import org.apache.commons.lang.NullArgumentException;
 
 /**
  * <p>Provides utilities for manipulating and examining 
- * <code>Throwable</code> objects.</p>
+<code>Throwable</code> objects.</p>
  *
  * @author <a href="mailto:dlr@finemaltcoding.com">Daniel Rall</a>
  * @author Dmitri Plotnikov
@@ -73,22 +74,40 @@
     };
 
     /**
-     * <p>The Method object for JDK1.4 getCause.</p>
+     * <p>
+     * The Method object for Java 1.4 getCause.
+     * </p>
      */
     private static final Method THROWABLE_CAUSE_METHOD;
+
+    /**
+     * <p>
+     * The Method object for Java 1.4 initCause.
+     * </p>
+     */
+    private static final Method THROWABLE_INITCAUSE_METHOD;
+    
     static {
-        Method getCauseMethod;
+        Method causeMethod;
         try {
-            getCauseMethod = Throwable.class.getMethod("getCause", null);
+            causeMethod = Throwable.class.getMethod("getCause", null);
         } catch (Exception e) {
-            getCauseMethod = null;
+            causeMethod = null;
         }
-        THROWABLE_CAUSE_METHOD = getCauseMethod;
+        THROWABLE_CAUSE_METHOD = causeMethod;
+        try {
+            causeMethod = Throwable.class.getMethod("initCause", new Class[]{Throwable.class});
+        } catch (Exception e) {
+            causeMethod = null;
+        }
+        THROWABLE_INITCAUSE_METHOD = causeMethod;
     }
     
     /**
-     * <p>Public constructor allows an instance of <code>ExceptionUtils</code>
-     * to be created, although that is not normally necessary.</p>
+     * <p>
+     * Public constructor allows an instance of <code>ExceptionUtils</code> to be created, although that is not
+     * normally necessary.
+     * </p>
      */
     public ExceptionUtils() {
         super();
@@ -130,6 +149,72 @@
     }
 
     /**
+     * <p>
+     * Sets the cause of a <code>Throwable</code> using introspection, allowing source code compatibility between
+     * pre-1.4 and post-1.4 Java releases.
+     * </p>
+     * 
+     * <p>
+     * The typical use of this method is inside a constructor as in the following example:
+     * </p>
+     * 
+     * <p>
+     * <pre>
+     * import org.apache.commons.lang.exception.ExceptionUtils;
+     *  
+     * public class MyException extends Exception {
+     *  
+     *    public MyException(String msg) {
+     *       super(msg);
+     *    }
+     *   
+     *    public MyException(String msg, Throwable cause) {
+     *       super(msg);
+     *       ExceptionUtils.setCause(this, cause);
+     *    }
+     * 
+     * }           
+     * </pre>
+     * </p>
+     * 
+     * @param target
+     *            the target <code>Throwable</code>
+     * @param cause
+     *            the <code>Throwable</code> to set in the target
+     * @return a <code>true</code> if the target has been modified
+     * @since 2.2
+     */
+    public static boolean setCause(Throwable target, Throwable cause) {
+        if (target == null) {
+            throw new NullArgumentException("target");
+        }
+        Object[] causeArgs = new Object[]{cause};
+        boolean modifiedTarget = false;
+        if (THROWABLE_INITCAUSE_METHOD != null) {
+            try {
+                THROWABLE_INITCAUSE_METHOD.invoke(target, causeArgs);
+                modifiedTarget = true;
+            } catch (IllegalAccessException ignored) {
+                // Exception ignored.
+            } catch (InvocationTargetException ignored) {
+                // Exception ignored.
+            }
+        }
+        try {
+            Method setCauseMethod = target.getClass().getMethod("setCause", new Class[]{Throwable.class});
+            setCauseMethod.invoke(target, causeArgs);
+            modifiedTarget = true;
+        } catch (NoSuchMethodException ignored) {
+            // Exception ignored.
+        } catch (IllegalAccessException ignored) {
+            // Exception ignored.
+        } catch (InvocationTargetException ignored) {
+            // Exception ignored.
+        }
+        return modifiedTarget;
+    }
+
+    /**
      * Returns the given list as a <code>String[]</code>.
      * @param list a list to transform.
      * @return the given list as a <code>String[]</code>.
@@ -768,14 +853,20 @@
     }
 
     /**
-     * <p>Returns an array where each element is a line from the argument.</p>
-     * <p>The end of line is determined by the value of {@link SystemUtils#LINE_SEPARATOR}.</p>
-     *  
-     * <p>Functionality shared between the
-     * <code>getStackFrames(Throwable)</code> methods of this and the
-     * {@link org.apache.commons.lang.exception.NestableDelegate}
-     * classes.</p>
-     * @param stackTrace A stack trace String.
+     * <p>
+     * Returns an array where each element is a line from the argument.
+     * </p>
+     * <p>
+     * The end of line is determined by the value of {@link SystemUtils#LINE_SEPARATOR}.
+     * </p>
+     * 
+     * <p>
+     * Functionality shared between the <code>getStackFrames(Throwable)</code> methods of this and the
+     * {@link org.apache.commons.lang.exception.NestableDelegate} classes.
+     * </p>
+     * 
+     * @param stackTrace
+     *            A stack trace String.
      * @return an array where each element is a line from the argument.
      */
     static String[] getStackFrames(String stackTrace) {

Modified: jakarta/commons/proper/lang/trunk/src/test/org/apache/commons/lang/exception/ExceptionUtilsTestCase.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/lang/trunk/src/test/org/apache/commons/lang/exception/ExceptionUtilsTestCase.java?rev=366225&r1=366224&r2=366225&view=diff
==============================================================================
--- jakarta/commons/proper/lang/trunk/src/test/org/apache/commons/lang/exception/ExceptionUtilsTestCase.java (original)
+++ jakarta/commons/proper/lang/trunk/src/test/org/apache/commons/lang/exception/ExceptionUtilsTestCase.java Thu Jan  5 09:35:43 2006
@@ -16,6 +16,7 @@
 package org.apache.commons.lang.exception;
 
 import java.io.ByteArrayOutputStream;
+import java.io.IOException;
 import java.io.PrintStream;
 import java.io.PrintWriter;
 import java.io.StringWriter;
@@ -25,6 +26,7 @@
 import junit.framework.Assert;
 import junit.framework.Test;
 import junit.framework.TestSuite;
+
 import org.apache.commons.lang.SystemUtils;
 
 /**
@@ -139,6 +141,25 @@
         assertSame(withoutCause, ExceptionUtils.getRootCause(withCause));
     }
 
+    public void testSetCause() {
+        Exception cause = new ExceptionWithoutCause();
+        assertEquals(true, ExceptionUtils.setCause(new ExceptionWithCause(null), cause));
+        if (SystemUtils.isJavaVersionAtLeast(140)) {
+            assertEquals(true, ExceptionUtils.setCause(new ExceptionWithoutCause(), cause));
+        }
+    }
+
+    /**
+     * Tests overriding a cause to <code>null</code>.
+     */
+    public void testSetCauseToNull() {
+        Exception ex = new ExceptionWithCause(new IOException());
+        assertEquals(true, ExceptionUtils.setCause(ex, new IllegalStateException()));
+        assertNotNull(ExceptionUtils.getCause(ex));
+        assertEquals(true, ExceptionUtils.setCause(ex, null));
+        assertNull(ExceptionUtils.getCause(ex));
+    }
+
     //-----------------------------------------------------------------------
     public void testIsThrowableNested() {
         if (SystemUtils.isJavaVersionAtLeast(140)) {
@@ -387,11 +408,15 @@
         private Throwable cause;
 
         public ExceptionWithCause(Throwable cause) {
-            this.cause = cause;
+            setCause(cause);
         }
 
         public Throwable getCause() {
             return cause;
+        }
+
+        public void setCause(Throwable cause) {
+            this.cause = cause;
         }
     }
 



---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org


Re: svn commit: r366225 - in /jakarta/commons/proper/lang/trunk/src: java/org/apache/commons/lang/exception/ExceptionUtils.java test/org/apache/commons/lang/exception/ExceptionUtilsTestCase.java

Posted by Stephen Colebourne <sc...@btopenworld.com>.
I hate whinging about formatting things, but there does seem to be an 
excess of whitespace here. The setCause javadoc is now so long that it 
doesn't fit in one page of my editor!

Its easy to assume that this doesn't matter because javadoc is read via 
HTML, but I know that I read a lot of javadoc in the source code, and I 
suspect many others do to. And when you do that you want minimal visual 
interference.

Stephen
(NB. I oppose all unecessary <p> & </p> as well, but [lang] voted to use 
them long ago)


ggregory@apache.org wrote:
>      /**
> -     * <p>The Method object for JDK1.4 getCause.</p>
> +     * <p>
> +     * The Method object for Java 1.4 getCause.
> +     * </p>
>       */

>      /**
> +     * <p>
> +     * Sets the cause of a <code>Throwable</code> using introspection, allowing source code compatibility between
> +     * pre-1.4 and post-1.4 Java releases.
> +     * </p>
> +     * 
> +     * <p>
> +     * The typical use of this method is inside a constructor as in the following example:
> +     * </p>
> +     * 
> +     * <p>
> +     * <pre>
> +     * import org.apache.commons.lang.exception.ExceptionUtils;
> +     *  
> +     * public class MyException extends Exception {
> +     *  
> +     *    public MyException(String msg) {
> +     *       super(msg);
> +     *    }
> +     *   
> +     *    public MyException(String msg, Throwable cause) {
> +     *       super(msg);
> +     *       ExceptionUtils.setCause(this, cause);
> +     *    }
> +     * 
> +     * }           
> +     * </pre>
> +     * </p>
> +     * 

---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org