Bug #14357 fixed. Mohan's patch makes removeCommonFrames public, and adds an
isThrowableNested to ExceptionUtils. It adds static attributes to decide if the stack trace should be topDown and if the stack traces should be trimmed on repeat. If running 1.4 or higher, it uses the default stack trace, and the functionality of NestableError, NestableException and NestableRuntimeException getMessage()s all change. Accompanying these changes are numerous tests. Submitted by: Mohan Kishore git-svn-id: https://svn.apache.org/repos/asf/jakarta/commons/proper/lang/trunk@137314 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
9d8cc76413
commit
82c5dada6f
|
@ -77,7 +77,7 @@ import org.apache.commons.lang.SystemUtils;
|
|||
* @author Dmitri Plotnikov
|
||||
* @author Stephen Colebourne
|
||||
* @since 1.0
|
||||
* @version $Id: ExceptionUtils.java,v 1.22 2003/03/23 17:47:51 scolebourne Exp $
|
||||
* @version $Id: ExceptionUtils.java,v 1.23 2003/05/14 02:59:13 bayard Exp $
|
||||
*/
|
||||
public class ExceptionUtils {
|
||||
/**
|
||||
|
@ -423,7 +423,7 @@ public class ExceptionUtils {
|
|||
* @param causeFrames stack trace of a cause throwable
|
||||
* @param wrapperFrames stack trace of a wrapper throwable
|
||||
*/
|
||||
private static void removeCommonFrames(List causeFrames, List wrapperFrames) {
|
||||
public static void removeCommonFrames(List causeFrames, List wrapperFrames) {
|
||||
int causeFrameIndex = causeFrames.size() - 1;
|
||||
int wrapperFrameIndex = wrapperFrames.size() - 1;
|
||||
while (causeFrameIndex >= 0 && wrapperFrameIndex >= 0) {
|
||||
|
@ -572,4 +572,19 @@ public class ExceptionUtils {
|
|||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
private static Object getCauseMethod = null;
|
||||
static {
|
||||
try {
|
||||
getCauseMethod = Throwable.class.getMethod("getCause", null);
|
||||
} catch (Exception e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Checks if the Throwable class has a <code>getCause</code> method.
|
||||
*/
|
||||
public static boolean isThrowableNested() {
|
||||
return (getCauseMethod != null);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -56,6 +56,7 @@ package org.apache.commons.lang.exception;
|
|||
import java.io.PrintStream;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* <code>NestableDelegate</code> is a shared implementation of the nestable
|
||||
|
@ -73,7 +74,7 @@ import java.io.StringWriter;
|
|||
* @author Sean C. Sullivan
|
||||
* @author Stephen Colebourne
|
||||
* @since 1.0
|
||||
* @version $Id: NestableDelegate.java,v 1.12 2003/01/25 13:06:26 scolebourne Exp $
|
||||
* @version $Id: NestableDelegate.java,v 1.13 2003/05/14 02:59:13 bayard Exp $
|
||||
*/
|
||||
public class NestableDelegate implements java.io.Serializable {
|
||||
|
||||
|
@ -90,6 +91,16 @@ public class NestableDelegate implements java.io.Serializable {
|
|||
* org.apache.commons.lang.exception.Nestable} implementation).
|
||||
*/
|
||||
private Throwable nestable = null;
|
||||
|
||||
/**
|
||||
* Whether to print the stack trace top-down.
|
||||
*/
|
||||
public static boolean topDown = true;
|
||||
|
||||
/**
|
||||
* Whether to trim the repeated stack trace.
|
||||
*/
|
||||
public static boolean trimStackFrames = true;
|
||||
|
||||
/**
|
||||
* Constructs a new <code>NestableDelegate</code> instance to manage the
|
||||
|
@ -266,30 +277,53 @@ public class NestableDelegate implements java.io.Serializable {
|
|||
|
||||
/**
|
||||
* Prints the stack trace of this exception to the specified
|
||||
* writer.
|
||||
* writer. If the Throwable class has a <code>getCause</code>
|
||||
* method (i.e. running on jre1.4 or higher), this method just
|
||||
* uses Throwable's printStackTrace() method. Otherwise, generates
|
||||
* the stack-trace, by taking into account the 'topDown' and
|
||||
* 'trimStackFrames' parameters. The topDown and trimStackFrames
|
||||
* are set to 'true' by default (produces jre1.4-like stack trace).
|
||||
*
|
||||
* @param out <code>PrintWriter</code> to use for output.
|
||||
*/
|
||||
public void printStackTrace(PrintWriter out) {
|
||||
synchronized (out) {
|
||||
String[] st = getStackFrames(this.nestable);
|
||||
Throwable nestedCause = ExceptionUtils.getCause(this.nestable);
|
||||
if (nestedCause != null) {
|
||||
if (nestedCause instanceof Nestable) {
|
||||
// Recurse until a non-Nestable is encountered.
|
||||
((Nestable) nestedCause).printStackTrace(out);
|
||||
} else {
|
||||
String[] nst = getStackFrames(nestedCause);
|
||||
for (int i = 0; i < nst.length; i++) {
|
||||
out.println(nst[i]);
|
||||
}
|
||||
}
|
||||
out.print("rethrown as ");
|
||||
Throwable throwable = this.nestable;
|
||||
// if running on jre1.4 or higher, use default printStackTrace
|
||||
if (ExceptionUtils.isThrowableNested()) {
|
||||
if (throwable instanceof Nestable) {
|
||||
((Nestable)throwable).printPartialStackTrace(out);
|
||||
} else {
|
||||
throwable.printStackTrace(out);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Output desired frames from stack trace.
|
||||
for (int i = 0; i < st.length; i++) {
|
||||
out.println(st[i]);
|
||||
// generating the nested stack trace
|
||||
List stacks = new ArrayList();
|
||||
while (throwable != null) {
|
||||
String[] st = getStackFrames(throwable);
|
||||
stacks.add(st);
|
||||
throwable = ExceptionUtils.getCause(throwable);
|
||||
}
|
||||
|
||||
// If NOT topDown, reverse the stack
|
||||
String separatorLine = "Caused by: ";
|
||||
if (!topDown) {
|
||||
separatorLine = "Rethrown as: ";
|
||||
Collections.reverse(stacks);
|
||||
}
|
||||
|
||||
// Remove the repeated lines in the stack
|
||||
if (trimStackFrames) trimStackFrames(stacks);
|
||||
|
||||
synchronized (out) {
|
||||
for (Iterator iter=stacks.iterator(); iter.hasNext();) {
|
||||
String[] st = (String[]) iter.next();
|
||||
for (int i=0, len=st.length; i < len; i++) {
|
||||
out.println(st[i]);
|
||||
}
|
||||
if (iter.hasNext())
|
||||
out.print(separatorLine);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -314,4 +348,31 @@ public class NestableDelegate implements java.io.Serializable {
|
|||
}
|
||||
return ExceptionUtils.getStackFrames(sw.getBuffer().toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Trims the stack frames. The first set is left untouched. The rest
|
||||
* of the frames are truncated from the bottom by comparing with
|
||||
* one just on top.
|
||||
*
|
||||
* @param stacks The list containing String[] elements
|
||||
*/
|
||||
private void trimStackFrames(List stacks) {
|
||||
for (int size=stacks.size(), i=size-1; i > 0; i--) {
|
||||
String[] curr = (String[]) stacks.get(i);
|
||||
String[] next = (String[]) stacks.get(i-1);
|
||||
|
||||
List currList = new ArrayList(Arrays.asList(curr));
|
||||
List nextList = new ArrayList(Arrays.asList(next));
|
||||
ExceptionUtils.removeCommonFrames(currList, nextList);
|
||||
|
||||
int trimmed = curr.length - currList.size();
|
||||
if (trimmed > 0) {
|
||||
currList.add("\t... "+trimmed+" more");
|
||||
stacks.set(
|
||||
i,
|
||||
(String[])currList.toArray(new String[currList.size()])
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -62,7 +62,7 @@ import java.io.PrintWriter;
|
|||
* @author <a href="mailto:dlr@finemaltcoding.com">Daniel Rall</a>
|
||||
* @see org.apache.commons.lang.exception.NestableException
|
||||
* @since 1.0
|
||||
* @version $Id: NestableError.java,v 1.5 2003/03/23 17:47:51 scolebourne Exp $
|
||||
* @version $Id: NestableError.java,v 1.6 2003/05/14 02:59:13 bayard Exp $
|
||||
*/
|
||||
public class NestableError extends Error implements Nestable {
|
||||
|
||||
|
@ -125,8 +125,19 @@ public class NestableError extends Error implements Nestable {
|
|||
return cause;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the detail message string of this throwable. If it was
|
||||
* created with a null message, returns the following:
|
||||
* (cause==null ? null : cause.toString()).
|
||||
*/
|
||||
public String getMessage() {
|
||||
return delegate.getMessage(super.getMessage());
|
||||
if (super.getMessage() != null) {
|
||||
return super.getMessage();
|
||||
} else if (cause != null) {
|
||||
return cause.toString();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public String getMessage(int index) {
|
||||
|
|
|
@ -70,7 +70,7 @@ import java.io.PrintWriter;
|
|||
* the way.
|
||||
* <p> Running the following program
|
||||
* <p><blockquote><pre>
|
||||
* 1 import org.apache.commons.NestedException;
|
||||
* 1 import org.apache.commons.lang.exception.NestableException;
|
||||
* 2
|
||||
* 3 public class Test {
|
||||
* 4 public static void main( String[] args ) {
|
||||
|
@ -85,7 +85,7 @@ import java.io.PrintWriter;
|
|||
* 13 try {
|
||||
* 14 b();
|
||||
* 15 } catch(Exception e) {
|
||||
* 16 throw new NestedException("foo", e);
|
||||
* 16 throw new NestableException("foo", e);
|
||||
* 17 }
|
||||
* 18 }
|
||||
* 19
|
||||
|
@ -93,7 +93,7 @@ import java.io.PrintWriter;
|
|||
* 21 try {
|
||||
* 22 c();
|
||||
* 23 } catch(Exception e) {
|
||||
* 24 throw new NestedException("bar", e);
|
||||
* 24 throw new NestableException("bar", e);
|
||||
* 25 }
|
||||
* 26 }
|
||||
* 27
|
||||
|
@ -104,15 +104,17 @@ import java.io.PrintWriter;
|
|||
* </pre></blockquote>
|
||||
* <p>Yields the following stacktrace:
|
||||
* <p><blockquote><pre>
|
||||
* java.lang.Exception: baz: bar: foo
|
||||
* at Test.c(Test.java:29)
|
||||
* at Test.b(Test.java:22)
|
||||
* rethrown as NestedException: bar
|
||||
* at Test.b(Test.java:24)
|
||||
* at Test.a(Test.java:14)
|
||||
* rethrown as NestedException: foo
|
||||
* at Test.a(Test.java:16)
|
||||
* at Test.main(Test.java:6)
|
||||
* org.apache.commons.lang.exception.NestableException: foo
|
||||
* at Test.a(Test.java:16)
|
||||
* at Test.main(Test.java:6)
|
||||
* Caused by: org.apache.commons.lang.exception.NestableException: bar
|
||||
* at Test.b(Test.java:24)
|
||||
* at Test.a(Test.java:14)
|
||||
* ... 1 more
|
||||
* Caused by: java.lang.Exception: baz
|
||||
* at Test.c(Test.java:29)
|
||||
* at Test.b(Test.java:22)
|
||||
* ... 2 more
|
||||
* </pre></blockquote><br>
|
||||
*
|
||||
* @author <a href="mailto:Rafal.Krzewski@e-point.pl">Rafal Krzewski</a>
|
||||
|
@ -120,7 +122,7 @@ import java.io.PrintWriter;
|
|||
* @author <a href="mailto:knielsen@apache.org">Kasper Nielsen</a>
|
||||
* @author <a href="mailto:steven@caswell.name">Steven Caswell</a>
|
||||
* @since 1.0
|
||||
* @version $Id: NestableException.java,v 1.7 2003/03/23 17:47:51 scolebourne Exp $
|
||||
* @version $Id: NestableException.java,v 1.8 2003/05/14 02:59:13 bayard Exp $
|
||||
*/
|
||||
public class NestableException extends Exception implements Nestable {
|
||||
|
||||
|
@ -183,8 +185,19 @@ public class NestableException extends Exception implements Nestable {
|
|||
return cause;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the detail message string of this throwable. If it was
|
||||
* created with a null message, returns the following:
|
||||
* (cause==null ? null : cause.toString()).
|
||||
*/
|
||||
public String getMessage() {
|
||||
return delegate.getMessage(super.getMessage());
|
||||
if (super.getMessage() != null) {
|
||||
return super.getMessage();
|
||||
} else if (cause != null) {
|
||||
return cause.toString();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public String getMessage(int index) {
|
||||
|
|
|
@ -66,7 +66,7 @@ import java.io.PrintWriter;
|
|||
* @author <a href="mailto:knielsen@apache.org">Kasper Nielsen</a>
|
||||
* @author <a href="mailto:steven@caswell.name">Steven Caswell</a>
|
||||
* @since 1.0
|
||||
* @version $Id: NestableRuntimeException.java,v 1.7 2003/03/23 17:47:51 scolebourne Exp $
|
||||
* @version $Id: NestableRuntimeException.java,v 1.8 2003/05/14 02:59:13 bayard Exp $
|
||||
*/
|
||||
public class NestableRuntimeException extends RuntimeException implements Nestable {
|
||||
|
||||
|
@ -129,8 +129,19 @@ public class NestableRuntimeException extends RuntimeException implements Nestab
|
|||
return cause;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the detail message string of this throwable. If it was
|
||||
* created with a null message, returns the following:
|
||||
* (cause==null ? null : cause.toString()).
|
||||
*/
|
||||
public String getMessage() {
|
||||
return delegate.getMessage(super.getMessage());
|
||||
if (super.getMessage() != null) {
|
||||
return super.getMessage();
|
||||
} else if (cause != null) {
|
||||
return cause.toString();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public String getMessage(int index) {
|
||||
|
|
|
@ -66,7 +66,7 @@ import junit.textui.TestRunner;
|
|||
* interface.
|
||||
*
|
||||
* @author <a href="mailto:steven@caswell.name">Steven Caswell</a>
|
||||
* @version $Id: AbstractNestableTestCase.java,v 1.2 2002/09/11 19:40:14 stevencaswell Exp $
|
||||
* @version $Id: AbstractNestableTestCase.java,v 1.3 2003/05/14 02:59:13 bayard Exp $
|
||||
*/
|
||||
public abstract class AbstractNestableTestCase extends TestCase
|
||||
{
|
||||
|
@ -152,33 +152,40 @@ public abstract class AbstractNestableTestCase extends TestCase
|
|||
|
||||
Nestable ne2 = getNestable("ne2");
|
||||
assertNotNull("nestable exception(\"ne2\") message is not null", ne2.getMessage());
|
||||
assertTrue("nestable exception(\"ne2\") message == ne2", ne2.getMessage().equals("ne2"));
|
||||
assertEquals("nestable exception(\"ne2\") message == ne2", ne2.getMessage(), "ne2");
|
||||
|
||||
Nestable ne3 = getNestable(getThrowable("ne3 exception"));
|
||||
assertNotNull("nestable exception(Throwable(\"ne3 exception\") message is not null",
|
||||
ne3.getMessage());
|
||||
assertTrue("nestable exception(Throwable(\"ne3 exception\") message == cause message",
|
||||
ne3.getMessage().equals(ne3.getCause().getMessage()));
|
||||
assertEquals("nestable exception(Throwable(\"ne3 exception\") message equals cause.toString()",
|
||||
ne3.getMessage(), ne3.getCause().toString());
|
||||
|
||||
Nestable ne4 = getNestable("ne4", getThrowable("ne4 exception"));
|
||||
assertNotNull("nestable exception(\"ne4\", Throwable(\"ne4 exception\") message is not null",
|
||||
ne4.getMessage());
|
||||
assertTrue("nestable exception(\"ne4\", Throwable(\"ne4 exception\") message == ne4: ne4 exception",
|
||||
ne4.getMessage().equals("ne4: ne4 exception"));
|
||||
assertEquals("nestable exception(\"ne4\", Throwable(\"ne4 exception\") message == ne4",
|
||||
ne4.getMessage(), "ne4");
|
||||
|
||||
Nestable ne5 = getNestable("ne5", (Throwable) null);
|
||||
assertNotNull("nestable exception(\"ne5\", null) message is not null",
|
||||
ne5.getMessage());
|
||||
assertTrue("nestable exception(\"ne5\", null) message == ne5",
|
||||
ne5.getMessage().equals("ne5"));
|
||||
assertEquals("nestable exception(\"ne5\", null) message == ne5",
|
||||
ne5.getMessage(), "ne5");
|
||||
|
||||
Nestable ne6 = getNestable(null, getThrowable("ne6 exception"));
|
||||
assertTrue("nestable exception(null, Throwable(\"ne6 exception\") cause == ne6 exception",
|
||||
ne6.getMessage().equals("ne6 exception"));
|
||||
Throwable t6 = getThrowable("ne6 exception");
|
||||
Nestable ne6 = getNestable(null, t6);
|
||||
assertNotNull("nestable exception(null, Throwable(\"ne6 exception\") message is not null",
|
||||
ne6.getMessage());
|
||||
assertEquals("nestable exception(null, Throwable(\"ne6 exception\") message equals cause.toString()",
|
||||
ne6.getMessage(), ne6.getCause().toString());
|
||||
|
||||
Nestable ne7 = getNestable("ne7o", getNestable("ne7i", getThrowable("ne7 exception")));
|
||||
assertTrue("nextable exception(\"ne7o\", getNestable(\"ne7i\", Throwable(\"ne7 exception\"))) message is ne7o: ne7i: ne7 exception",
|
||||
ne7.getMessage().equals("ne7o: ne7i: ne7 exception"));
|
||||
assertEquals("nestable exception(\"ne7o\", getNestable(\"ne7i\", Throwable(\"ne7 exception\"))) message is ne7o: ne7i: ne7 exception",
|
||||
ne7.getMessage(), "ne7o");
|
||||
|
||||
Nestable ne8 = getNestable();
|
||||
assertNull("nestable exception() message is null",
|
||||
ne8.getMessage());
|
||||
|
||||
}
|
||||
|
||||
|
@ -513,7 +520,7 @@ public abstract class AbstractNestableTestCase extends TestCase
|
|||
PrintWriter pw2 = new PrintWriter(ps2, true);
|
||||
ne9.printPartialStackTrace(pw2);
|
||||
String stack2 = baos2.toString();
|
||||
String startsWith = ne9.getClass().getName() + ": ne9: ne9 exception";
|
||||
String startsWith = ne9.getClass().getName() + ": ne9";
|
||||
assertTrue("stack trace startsWith == " + startsWith,
|
||||
stack2.startsWith(startsWith));
|
||||
assertEquals("stack trace indexOf rethrown == -1",
|
||||
|
@ -529,12 +536,12 @@ public abstract class AbstractNestableTestCase extends TestCase
|
|||
ByteArrayOutputStream baos1 = new ByteArrayOutputStream();
|
||||
PrintStream ps1 = new PrintStream(baos1);
|
||||
PrintWriter pw1 = new PrintWriter(ps1, true);
|
||||
ne8.printStackTrace(ps1);
|
||||
ne8.printStackTrace(pw1);
|
||||
String stack1 = baos1.toString();
|
||||
String startsWith = getThrowableClass().getName() + ": ne8 exception";
|
||||
String startsWith = ne8.getClass().getName() + ": ne8";
|
||||
assertTrue("stack trace startsWith == " + startsWith,
|
||||
stack1.startsWith(startsWith));
|
||||
String indexOf = ne8.getClass().getName() + ": ne8: ne8 exception";
|
||||
String indexOf = getThrowableClass().getName() + ": ne8 exception";
|
||||
assertTrue("stack trace indexOf " + indexOf + " > -1",
|
||||
stack1.indexOf(indexOf) > -1);
|
||||
}
|
||||
|
|
|
@ -65,7 +65,7 @@ import junit.textui.TestRunner;
|
|||
*
|
||||
* @author <a href="mailto:steven@caswell.name">Steven Caswell</a>
|
||||
* @author <a href="mailto:dlr@finemaltcoding.com">Daniel Rall</a>
|
||||
* @version $Id: NestableDelegateTestCase.java,v 1.3 2002/09/18 15:51:41 stevencaswell Exp $
|
||||
* @version $Id: NestableDelegateTestCase.java,v 1.4 2003/05/14 02:59:13 bayard Exp $
|
||||
*/
|
||||
public class NestableDelegateTestCase extends junit.framework.TestCase
|
||||
{
|
||||
|
@ -73,7 +73,7 @@ public class NestableDelegateTestCase extends junit.framework.TestCase
|
|||
"The Nestable implementation passed to the NestableDelegate(Nestable) constructor must extend java.lang.Throwable";
|
||||
|
||||
private static final String PARTIAL_STACK_TRACE =
|
||||
"rethrown as ThrowableNestedNestable partial stack trace place-holder";
|
||||
"ThrowableNestedNestable partial stack trace place-holder";
|
||||
|
||||
protected String lineSeparator;
|
||||
|
||||
|
@ -174,7 +174,15 @@ public class NestableDelegateTestCase extends junit.framework.TestCase
|
|||
d = new NestableDelegate(n);
|
||||
doNestableDelegateGetThrowableCount(d, 2);
|
||||
|
||||
n = new NestableDelegateTester1("level 1", new NestableDelegateTester2("level 2", new NestableDelegateTester1(new NestableDelegateTester2("level 4", new Exception("level 5")))));
|
||||
n = new NestableDelegateTester1("level 1",
|
||||
new NestableDelegateTester2("level 2",
|
||||
new NestableDelegateTester1(
|
||||
new NestableDelegateTester2("level 4",
|
||||
new Exception("level 5")
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
d = new NestableDelegate(n);
|
||||
doNestableDelegateGetThrowableCount(d, 5);
|
||||
}
|
||||
|
@ -220,7 +228,15 @@ public class NestableDelegateTestCase extends junit.framework.TestCase
|
|||
msgs[2] = null;
|
||||
msgs[3] = "level 4";
|
||||
msgs[4] = "level 5";
|
||||
n = new NestableDelegateTester1(msgs[0], new NestableDelegateTester2(msgs[1], new NestableDelegateTester1(new NestableDelegateTester2(msgs[3], new Exception(msgs[4])))));
|
||||
n = new NestableDelegateTester1(msgs[0],
|
||||
new NestableDelegateTester2(msgs[1],
|
||||
new NestableDelegateTester1(
|
||||
new NestableDelegateTester2(msgs[3],
|
||||
new Exception(msgs[4])
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
d = new NestableDelegate(n);
|
||||
doNestableDelegateGetMessages(d, msgs);
|
||||
}
|
||||
|
@ -246,7 +262,15 @@ public class NestableDelegateTestCase extends junit.framework.TestCase
|
|||
msgs[2] = null;
|
||||
msgs[3] = "level 4";
|
||||
msgs[4] = "level 5";
|
||||
n = new NestableDelegateTester1(msgs[0], new NestableDelegateTester2(msgs[1], new NestableDelegateTester1(new NestableDelegateTester2(msgs[3], new Exception(msgs[4])))));
|
||||
n = new NestableDelegateTester1(msgs[0],
|
||||
new NestableDelegateTester2(msgs[1],
|
||||
new NestableDelegateTester1(
|
||||
new NestableDelegateTester2(msgs[3],
|
||||
new Exception(msgs[4])
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
d = new NestableDelegate(n);
|
||||
for(int i = 0; i < msgs.length; i++)
|
||||
{
|
||||
|
@ -301,7 +325,15 @@ public class NestableDelegateTestCase extends junit.framework.TestCase
|
|||
throwables[2] = NestableDelegateTester1.class;
|
||||
throwables[3] = NestableDelegateTester2.class;
|
||||
throwables[4] = Exception.class;
|
||||
n = new NestableDelegateTester1(msgs[0], new NestableDelegateTester2(msgs[1], new NestableDelegateTester1(new NestableDelegateTester2(msgs[3], new Exception(msgs[4])))));
|
||||
n = new NestableDelegateTester1(msgs[0],
|
||||
new NestableDelegateTester2(msgs[1],
|
||||
new NestableDelegateTester1(
|
||||
new NestableDelegateTester2(msgs[3],
|
||||
new Exception(msgs[4])
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
d = new NestableDelegate(n);
|
||||
doNestableDelegateGetThrowableN(d, throwables, msgs);
|
||||
}
|
||||
|
@ -374,7 +406,15 @@ public class NestableDelegateTestCase extends junit.framework.TestCase
|
|||
throwables[2] = NestableDelegateTester1.class;
|
||||
throwables[3] = NestableDelegateTester2.class;
|
||||
throwables[4] = Exception.class;
|
||||
n = new NestableDelegateTester1(msgs[0], new NestableDelegateTester2(msgs[1], new NestableDelegateTester1(new NestableDelegateTester2(msgs[3], new Exception(msgs[4])))));
|
||||
n = new NestableDelegateTester1(msgs[0],
|
||||
new NestableDelegateTester2(msgs[1],
|
||||
new NestableDelegateTester1(
|
||||
new NestableDelegateTester2(msgs[3],
|
||||
new Exception(msgs[4])
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
d = new NestableDelegate(n);
|
||||
doNestableDelegateGetThrowables(d, throwables, msgs);
|
||||
}
|
||||
|
@ -422,7 +462,15 @@ public class NestableDelegateTestCase extends junit.framework.TestCase
|
|||
throwables[3] = NestableDelegateTester2.class;
|
||||
throwables[4] = Exception.class;
|
||||
int[] indexes = {0, 1, 0, 1, 4};
|
||||
n = new NestableDelegateTester1(msgs[0], new NestableDelegateTester2(msgs[1], new NestableDelegateTester1(new NestableDelegateTester2(msgs[3], new Exception(msgs[4])))));
|
||||
n = new NestableDelegateTester1(msgs[0],
|
||||
new NestableDelegateTester2(msgs[1],
|
||||
new NestableDelegateTester1(
|
||||
new NestableDelegateTester2(msgs[3],
|
||||
new Exception(msgs[4])
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
d = new NestableDelegate(n);
|
||||
for(int i = 0; i < throwables.length; i++)
|
||||
{
|
||||
|
@ -490,26 +538,52 @@ public class NestableDelegateTestCase extends junit.framework.TestCase
|
|||
PrintStream ps1 = new PrintStream(baos1);
|
||||
nd3.printStackTrace(ps1);
|
||||
String stack1 = baos1.toString();
|
||||
assertTrue("stack trace startsWith == java.lang.Exception: nested exception 3",
|
||||
stack1.startsWith("java.lang.Exception: nested exception 3"));
|
||||
int start1 = (stack1.length() - lineSepLen) - partialStackTraceLen;
|
||||
int end1 = stack1.length() - lineSepLen;
|
||||
assertEquals("stack trace substring(" + start1 + "," + end1 + ") == " +
|
||||
PARTIAL_STACK_TRACE,
|
||||
PARTIAL_STACK_TRACE,
|
||||
stack1.substring(start1, end1));
|
||||
assertTrue("stack trace startsWith", stack1.startsWith(PARTIAL_STACK_TRACE));
|
||||
|
||||
ByteArrayOutputStream baos2 = new ByteArrayOutputStream();
|
||||
PrintStream ps2 = new PrintStream(baos2);
|
||||
System.setErr(ps2);
|
||||
nd3.printStackTrace();
|
||||
String stack2 = baos2.toString();
|
||||
assertTrue("stack trace startsWith == java.lang.Exception: nested exception 3",
|
||||
stack2.startsWith("java.lang.Exception: nested exception 3"));
|
||||
int start2 = (stack2.length() - lineSepLen) - partialStackTraceLen;
|
||||
int end2 = stack2.length() - lineSepLen;
|
||||
assertTrue("stack trace substring(" + start2 + "," + end2 + ") == " + PARTIAL_STACK_TRACE,
|
||||
stack2.substring(start2, end2).equals(PARTIAL_STACK_TRACE));
|
||||
Nestable n = new NestableDelegateTester1("level 1",
|
||||
new NestableDelegateTester2("level 2",
|
||||
new NestableDelegateTester1(
|
||||
new NestableDelegateTester2("level 4",
|
||||
new Exception("level 5")
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
NestableDelegate d = new NestableDelegate(n);
|
||||
|
||||
// Only testing the flags for jdk1.3 and below
|
||||
if (!ExceptionUtils.isThrowableNested()) {
|
||||
d.topDown = true; d.trimStackFrames = true;
|
||||
checkStackTrace(d, true, true, NestableDelegateTester1.class.getName()+": level 1", 24);
|
||||
d.topDown = true; d.trimStackFrames = false;
|
||||
checkStackTrace(d, true, false, NestableDelegateTester1.class.getName()+": level 1", 80);
|
||||
d.topDown = false; d.trimStackFrames = true;
|
||||
checkStackTrace(d, false, true, "java.lang.Exception: level 5", 24);
|
||||
d.topDown = false; d.trimStackFrames = false;
|
||||
checkStackTrace(d, false, false, "java.lang.Exception: level 5", 80);
|
||||
d.topDown = true; d.trimStackFrames = true;
|
||||
}
|
||||
}
|
||||
private void checkStackTrace(NestableDelegate d, boolean topDown, boolean trimStackFrames,
|
||||
String startsWith, int expCount) {
|
||||
ByteArrayOutputStream baos1 = new ByteArrayOutputStream();
|
||||
PrintStream ps1 = new PrintStream(baos1);
|
||||
d.printStackTrace(ps1);
|
||||
String stack1 = baos1.toString();
|
||||
int actCount = countLines(stack1);
|
||||
assertTrue("topDown: "+topDown+", trimStackFrames: "+trimStackFrames+" startsWith",
|
||||
stack1.startsWith(startsWith));
|
||||
assertEquals("topDown: "+topDown+", trimStackFrames: "+trimStackFrames+" lineCount",
|
||||
expCount, actCount);
|
||||
}
|
||||
private int countLines(String s) {
|
||||
if (s == null) return 0;
|
||||
|
||||
int i = 0, ndx = -1;
|
||||
while ((ndx = s.indexOf("\n", ndx+1)) != -1) {
|
||||
i++;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
public static void main(String args[])
|
||||
|
@ -518,6 +592,11 @@ public class NestableDelegateTestCase extends junit.framework.TestCase
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Nestable and Throwable class which can be passed to the NestableDelegate
|
||||
* constructor. Used for testing various methods which iterate through the
|
||||
* nested causes.
|
||||
*/
|
||||
class NestableDelegateTester1 extends Exception implements Nestable
|
||||
{
|
||||
private Throwable cause = null;
|
||||
|
@ -605,6 +684,7 @@ class NestableDelegateTester1 extends Exception implements Nestable
|
|||
*/
|
||||
public void printPartialStackTrace(PrintWriter out)
|
||||
{
|
||||
super.printStackTrace(out);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -633,6 +713,11 @@ class NestableDelegateTester1 extends Exception implements Nestable
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* Nestable and Throwable class which can be passed to the NestableDelegate
|
||||
* constructor. Used for testing various methods which iterate through the
|
||||
* nested causes.
|
||||
*/
|
||||
class NestableDelegateTester2 extends Throwable implements Nestable
|
||||
{
|
||||
private Throwable cause = null;
|
||||
|
@ -722,6 +807,7 @@ class NestableDelegateTester2 extends Throwable implements Nestable
|
|||
*/
|
||||
public void printPartialStackTrace(PrintWriter out)
|
||||
{
|
||||
super.printStackTrace(out);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -750,6 +836,11 @@ class NestableDelegateTester2 extends Throwable implements Nestable
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to test that the constructor passes when passed a throwable cause
|
||||
* And, the NestableDelegate.getMessage() returns the message from underlying
|
||||
* nestable (which also has to be a Throwable).
|
||||
*/
|
||||
class ThrowableNestable extends Throwable implements Nestable
|
||||
{
|
||||
private Throwable cause = new Exception("ThrowableNestable cause");
|
||||
|
@ -860,6 +951,11 @@ class ThrowableNestable extends Throwable implements Nestable
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* Nestable and Throwable class which takes in a 'cause' object.
|
||||
* Returns a message wrapping the 'cause' message
|
||||
* Prints a fixed stack trace and partial stack trace.
|
||||
*/
|
||||
class ThrowableNestedNestable extends Throwable implements Nestable
|
||||
{
|
||||
private Throwable cause = null;
|
||||
|
@ -980,6 +1076,9 @@ class ThrowableNestedNestable extends Throwable implements Nestable
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to test that the constructor fails when passed a non-throwable cause
|
||||
*/
|
||||
class NonThrowableNestable implements Nestable
|
||||
{
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue