
org.enhydra.error.ChainedThrowableSupport Maven / Gradle / Ivy
The newest version!
/*
* Enhydra Java Application Server Project
*
* The contents of this file are subject to the Enhydra Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License on
* the Enhydra web site ( http://www.enhydra.org/ ).
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific terms governing rights and limitations
* under the License.
*
* The Initial Developer of the Enhydra Application Server is Lutris
* Technologies, Inc. The Enhydra Application Server and portions created
* by Lutris Technologies, Inc. are Copyright Lutris Technologies, Inc.
* All Rights Reserved.
*
* Contributor(s):
*
* $Id: ChainedThrowableSupport.java,v 1.2 2005/01/26 08:29:24 jkjome Exp $
*/
package org.enhydra.error;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* Static methods used to implement the Chained* throwables.
*/
public final class ChainedThrowableSupport {
/** Name of SAXException class. */
private static final String SAX_EXCEPTION_CLASS = "org.xml.sax.SAXException";
/**
* Can't makes instances of this class.
*/
private ChainedThrowableSupport() {
}
/**
* Generate the message to set for the exception message when an explict
* message is not available. The message is derived from the causing
* exception. Used to support constructor that take only a cause
* {@link Throwable Throwable} as an argument. This method is used to
* generate the message to has to the super constructor.
*
* @param cause The causing exception, which maybe null.
*/
public static String makeMessage(Throwable cause) {
if (cause == null) {
return null;
} else {
String causeMsg = cause.getMessage();
if (causeMsg == null) {
return cause.getClass().getName();
} else {
return causeMsg;
}
}
}
/**
* Get the message associated with this exception.
* @param except The chained throwable generating the
* message.
* @param superMsg The result of super.getMessage(), so
* that the contained messages is available. Maybe null.
*/
public static String getMessage(ChainedThrowable except,
String superMsg) {
if (superMsg != null) {
return superMsg;
}
Thread thread = Thread.currentThread();
String threadMsg = " " + thread + " (" + thread.getThreadGroup().getName() + ", " + thread.getName() + ")";
Throwable cause = except.getCause();
if (cause == null) {
return except.getClass().getName() + threadMsg;
} else {
String causeMsg = cause.getMessage();
if ((causeMsg == null) || (causeMsg.length() == 0)) {
causeMsg = cause.getClass().getName();
}
return causeMsg + threadMsg;
}
}
/**
* Get the localhist message associated with this exception.
* @param except The chained throwable generating the message.
* @param superMsg The result of super.getLocalizedMessage(), so
* that the contained messages is available. Maybe null.
*/
public static String getLocalizedMessage(ChainedThrowable except,
String superMsg) {
if (superMsg != null) {
return superMsg;
}
Throwable cause = except.getCause();
if (cause == null) {
return except.getClass().getName();
} else {
String causeMsg = cause.getLocalizedMessage();
if ((causeMsg == null) || (causeMsg.length() == 0)) {
causeMsg = cause.getClass().getName();
}
return causeMsg;
}
}
/**
* Check if this is one of the many java.* classes that contained
* a chained throwable.
*/
private static Throwable getJavaChain(Throwable cause) {
if (cause instanceof java.io.WriteAbortedException) {
return ((java.io.WriteAbortedException)cause).detail;
} else if (cause instanceof java.lang.ClassNotFoundException) {
return ((java.lang.ClassNotFoundException)cause).getException();
} else if (cause instanceof java.lang.ExceptionInInitializerError) {
return ((java.lang.ExceptionInInitializerError)cause).getException();
} else if (cause instanceof java.lang.reflect.InvocationTargetException) {
return ((java.lang.reflect.InvocationTargetException)cause).getTargetException();
} else if (cause instanceof java.rmi.RemoteException) {
return ((java.rmi.RemoteException)cause).detail;
} else if (cause instanceof java.rmi.activation.ActivationException) {
return ((java.rmi.activation.ActivationException)cause).detail;
} else if (cause instanceof java.rmi.server.ServerCloneException) {
return ((java.rmi.server.ServerCloneException)cause).detail;
} else if (cause instanceof java.security.PrivilegedActionException) {
return ((java.security.PrivilegedActionException)cause).getException();
} else if (cause instanceof java.sql.SQLException) {
return ((java.sql.SQLException)cause).getNextException();
} else {
return null;
}
}
/**
* Obtain a chain cause via an parameterless method accessed through
* reflection.
*/
private static Throwable getChainWithAccessor(Throwable cause,
String accessorName)
throws NoSuchMethodException, IllegalAccessException,
InvocationTargetException {
Method accessor = cause.getClass().getMethod(accessorName, (Class[])null);
return (Throwable)accessor.invoke(cause, (Object[])null);
}
/**
* Check for AWT exception with a chain. These are treated as optional,
* despite being a java.* class, since a server-only JVM might not
* include them.
*/
private static Throwable getAWTChain(Throwable cause)
throws NoSuchMethodException, IllegalAccessException,
InvocationTargetException {
if (cause.getClass().getName().equals("java.awt.print.PrinterIOException")) {
return getChainWithAccessor(cause, "getIOException");
} else {
return null;
}
}
/**
* Check if an exception is a SAXException without actually referencing
* the class.
*/
private static boolean isSAXException(Throwable except) {
return except.getClass().getName().equals(SAX_EXCEPTION_CLASS);
}
/**
* Check SAXException chain.
*/
private static Throwable getSAXExceptionChain(Throwable cause)
throws NoSuchMethodException, IllegalAccessException,
InvocationTargetException {
if (isSAXException(cause)) {
return getChainWithAccessor(cause, "getException");
} else {
return null;
}
}
/**
* Do work of printing the causes of a chained exception. This is
* recursive. This attempts to following causing exceptions that are
* chained in other types of exception objects. If only Sun would
* standardize a mechanism in throwable. For classes that are
* not part of the standard runtime we access them by reflection,
* as this class if often lower down in the class loader hierarchy.
*/
private static void printChainedCauses(Throwable cause,
PrintWriter out) {
if (cause != null) {
out.println("*** Caused by:"); //FIXME: I18N
if (isSAXException(cause)) {
// SAXException `hides' itself when printing the stack by
// overriding toString() to print the contained exception,
// we print something extra to keep this from being confusing
out.print(SAX_EXCEPTION_CLASS);
out.print(": ");
}
cause.printStackTrace(out);
try {
// If cause was is a ChainedThrowable, its chain has already
// been followed, otherwise, see what we can do.
if (!(cause instanceof ChainedThrowable)) {
Throwable nextCause = getJavaChain(cause);
if (nextCause == null) {
nextCause = getAWTChain(cause);
}
if (nextCause == null) {
nextCause = getSAXExceptionChain(cause);
}
if (nextCause != null) {
printChainedCauses(nextCause, out);
}
}
} catch (Throwable except) {
// Can't find one of the chained exceptions
out.println("WARNING: can't print rest of exception chain: "
+ except);
}
}
}
/**
* Prints stacktrace and cause stacktrace.
*/
public static void printCauseTrace(ChainedThrowable except) {
PrintWriter pw = new PrintWriter(System.err);
printChainedCauses(except.getCause(), pw);
pw.flush();
}
/**
* Prints stacktrace and cause stacktrace.
*/
public static void printCauseTrace(ChainedThrowable except,
PrintStream s) {
PrintWriter pw = new PrintWriter(s);
printChainedCauses(except.getCause(), pw);
pw.flush();
}
/**
* Prints stacktrace and cause stacktrace.
*/
public static void printCauseTrace(ChainedThrowable except,
PrintWriter out) {
printChainedCauses(except.getCause(), out);
out.flush();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy