You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by st...@apache.org on 2011/08/05 16:26:15 UTC
svn commit: r1154237 - in /maven/sandbox/trunk/plexus-utils-commons-bridge:
plexus-utils-commons-bridge/src/main/java/org/codehaus/plexus/util/ExceptionUtils.java
plexus-utils-tck/src/test/java/org/codehaus/plexus/util/ExceptionUtilsTest.java
Author: struberg
Date: Fri Aug 5 14:26:15 2011
New Revision: 1154237
URL: http://svn.apache.org/viewvc?rev=1154237&view=rev
Log:
ExceptionUtils implementation continued
Modified:
maven/sandbox/trunk/plexus-utils-commons-bridge/plexus-utils-commons-bridge/src/main/java/org/codehaus/plexus/util/ExceptionUtils.java
maven/sandbox/trunk/plexus-utils-commons-bridge/plexus-utils-tck/src/test/java/org/codehaus/plexus/util/ExceptionUtilsTest.java
Modified: maven/sandbox/trunk/plexus-utils-commons-bridge/plexus-utils-commons-bridge/src/main/java/org/codehaus/plexus/util/ExceptionUtils.java
URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/plexus-utils-commons-bridge/plexus-utils-commons-bridge/src/main/java/org/codehaus/plexus/util/ExceptionUtils.java?rev=1154237&r1=1154236&r2=1154237&view=diff
==============================================================================
--- maven/sandbox/trunk/plexus-utils-commons-bridge/plexus-utils-commons-bridge/src/main/java/org/codehaus/plexus/util/ExceptionUtils.java (original)
+++ maven/sandbox/trunk/plexus-utils-commons-bridge/plexus-utils-commons-bridge/src/main/java/org/codehaus/plexus/util/ExceptionUtils.java Fri Aug 5 14:26:15 2011
@@ -21,6 +21,10 @@ package org.codehaus.plexus.util;
import java.io.PrintStream;
import java.io.PrintWriter;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.sql.SQLException;
+import java.util.concurrent.CopyOnWriteArrayList;
/**
* ExceptionUtils contains helper methods for treating Throwable objects.
@@ -34,6 +38,25 @@ import java.io.PrintWriter;
public class ExceptionUtils
{
/**
+ * The maximum level of nestings evaluated when searching for a root cause.
+ * We do this to prevent stack overflows!
+ *
+ * @see #getRootCause(Throwable)
+ * @see #getRootCauseStackTrace(Throwable)
+ */
+ private static final int MAX_ROOT_CAUSE_DEPTH = 20;
+
+ private static CopyOnWriteArrayList<String> specialCauseMethodNames = new CopyOnWriteArrayList<String>();
+ static
+ {
+ specialCauseMethodNames.add( "getException" );
+ specialCauseMethodNames.add( "getSourceException" );
+ specialCauseMethodNames.add( "getRootCause" );
+ specialCauseMethodNames.add( "getCausedByException" );
+ specialCauseMethodNames.add( "getNested" );
+ }
+
+ /**
* This method is only here for backward compat reasons.
* It's original means was to add additional method names
* which got checked to determine if the Throwable in question
@@ -46,28 +69,157 @@ public class ExceptionUtils
@Deprecated
public static void addCauseMethodName( String methodName )
{
- // we don't need this anymore!
+ specialCauseMethodNames.add(methodName);
}
+ /**
+ * The {@link Throwable#getCause()} of the given Throwable.
+ *
+ * @param throwable
+ *
+ * @return the cause of the given Throwable, <code>null</code> if no cause exists.
+ */
public static Throwable getCause( Throwable throwable )
{
- System.out.println("TODO IMPLEMENT");
- //X TODO implement
- return null;
+ Throwable retVal = throwable.getCause();
+
+ if ( retVal == null)
+ {
+
+ retVal = getCause( throwable
+ , specialCauseMethodNames.toArray( new String[ specialCauseMethodNames.size() ] ) );
+ }
+
+ return retVal;
}
+ /**
+ * Get the cause of the given throwable if any by using the given methodNames
+ *
+ * @param throwable
+ * @param methodNames
+ * @return
+ */
public static Throwable getCause( Throwable throwable, String[] methodNames )
{
- System.out.println("TODO IMPLEMENT");
- //X TODO implement
- return null;
+ Throwable retVal = null;
+
+ // first try a few standard Exception types we already know
+ if ( retVal == null && throwable instanceof SQLException )
+ {
+ retVal = ((SQLException) throwable).getNextException();
+ }
+
+ if ( retVal == null && throwable instanceof InvocationTargetException)
+ {
+ retVal = ((InvocationTargetException) throwable).getTargetException();
+ }
+
+ if ( retVal == null )
+ {
+ for ( String methodName : methodNames )
+ {
+ if ( methodName == null )
+ {
+ continue;
+ }
+
+ retVal = getCauseByMethodName( throwable, methodName );
+ if ( retVal != null )
+ {
+ return retVal;
+ }
+ }
+ }
+
+ return retVal;
+ }
+
+ /**
+ * Internal method to get the cause of a given Throwable by a specified methods name.
+ *
+ * @param throwable
+ * @param methodName
+ * @return the cause or <code>null</code> if either the method doesn't exist or there is no cause.
+ */
+ private static Throwable getCauseByMethodName( Throwable throwable, String methodName )
+ {
+ Method method;
+ try
+ {
+ method = throwable.getClass().getMethod( methodName, null );
+ }
+ catch (NoSuchMethodException e)
+ {
+ return null;
+ }
+
+ if ( method.getReturnType() == null || !method.getReturnType().isAssignableFrom( Throwable.class ) )
+ {
+ return null;
+ }
+
+ try
+ {
+ return (Throwable) method.invoke( throwable );
+ }
+ catch (IllegalAccessException e)
+ {
+ return null;
+ }
+ catch (InvocationTargetException e)
+ {
+ return null;
+ }
}
+
+ /**
+ * Go down the {@link Throwable#getCause()} chain to find the
+ * source of the problem. For nested Throwables, this will return
+ * the recursively deepest Throwable in the chain.
+ *
+ * @param throwable
+ *
+ * @return the original cause of the Throwable
+ */
public static Throwable getRootCause( Throwable throwable )
{
- System.out.println("TODO IMPLEMENT");
- //X TODO implement
- return null;
+ if ( throwable == null )
+ {
+ throw new NullPointerException( "Throwable in ExceptionUtils#getRootCause must not be null!" );
+ }
+
+ Throwable rootCause = throwable;
+ int depth = 0;
+
+ while ( rootCause != null )
+ {
+ if ( depth >= MAX_ROOT_CAUSE_DEPTH )
+ {
+ // maximum depth level reached!
+ return rootCause;
+ }
+
+ Throwable nextRootCause = getCause( rootCause );
+
+ if ( nextRootCause == null )
+ {
+ if ( depth == 0 )
+ {
+ return null;
+ }
+ else
+ {
+ return rootCause;
+ }
+ }
+
+ rootCause = nextRootCause;
+ depth++;
+ }
+
+ return rootCause;
}
public static int getThrowableCount( Throwable throwable )
Modified: maven/sandbox/trunk/plexus-utils-commons-bridge/plexus-utils-tck/src/test/java/org/codehaus/plexus/util/ExceptionUtilsTest.java
URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/plexus-utils-commons-bridge/plexus-utils-tck/src/test/java/org/codehaus/plexus/util/ExceptionUtilsTest.java?rev=1154237&r1=1154236&r2=1154237&view=diff
==============================================================================
--- maven/sandbox/trunk/plexus-utils-commons-bridge/plexus-utils-tck/src/test/java/org/codehaus/plexus/util/ExceptionUtilsTest.java (original)
+++ maven/sandbox/trunk/plexus-utils-commons-bridge/plexus-utils-tck/src/test/java/org/codehaus/plexus/util/ExceptionUtilsTest.java Fri Aug 5 14:26:15 2011
@@ -111,6 +111,13 @@ public class ExceptionUtilsTest extends
, ExceptionUtils.getCause( testException )
, equalTo( (Throwable) npe ) );
}
+
+ }
+
+ @Test( expected = NullPointerException.class )
+ public void testGetCause_Null()
+ {
+ ExceptionUtils.getCause( null );
}
@Test