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    }