001 package org.shiftone.jrat.util;
002
003
004 import java.io.PrintStream;
005 import java.io.PrintWriter;
006 import java.lang.reflect.Method;
007
008
009 /**
010 * Ok.. before Java 1.4 - exceptions did not have a cause.
011 *
012 * @author jeff@shiftone.org (Jeff Drost)
013 */
014 public class NestedRuntimeException extends RuntimeException {
015
016 private Throwable rootCause = null;
017
018 public NestedRuntimeException(String message) {
019 super(message);
020 }
021
022
023 public NestedRuntimeException(String message, Throwable rootCause) {
024
025 super(message);
026
027 initializeCause(rootCause);
028 }
029
030
031 private void initializeCause(Throwable rootCause) {
032
033 try {
034
035 // the idea here is to try to use the java 1.4 cause, but it that's
036 // not possible,
037 // fall back to the custom rootCause field
038 // --> public synchronized Throwable initCause(Throwable cause);
039 Method initCause = Throwable.class.getMethod("initCause", new Class[]{Throwable.class});
040
041 initCause.invoke(this, new Object[]{rootCause});
042 }
043 catch (Exception e) {
044 this.rootCause = rootCause;
045 }
046 }
047
048
049 public Throwable getRootCause() {
050 return rootCause;
051 }
052
053
054 public void printStackTrace() {
055 printStackTrace(System.out);
056 }
057
058
059 public void printStackTrace(PrintStream s) {
060 printStackTrace(new PrintWriter(s));
061 }
062
063
064 public void printStackTrace(PrintWriter s) {
065
066 super.printStackTrace(s);
067
068 if (rootCause != null) {
069 s.println("** ROOT CAUSE");
070 rootCause.printStackTrace(s);
071 }
072 }
073 }