diff --git a/Java/commons-lang-EnumUtils_113/Dockerfile b/Java/commons-lang-EnumUtils_113/Dockerfile new file mode 100644 index 000000000..7b7fbe349 --- /dev/null +++ b/Java/commons-lang-EnumUtils_113/Dockerfile @@ -0,0 +1,18 @@ +FROM ghcr.io/kupl/starlab-benchmarks/java-base:commons-lang + +ENV TZ=Asia/Seoul + +COPY ./metadata.json . +COPY ./npe.json . +COPY ./buggy.java /tmp/buggy.java +RUN export BUGGY_PATH=$(cat metadata.json | jq -r ".npe.filepath") \ + && export BUGGY_LINE=$(cat metadata.json | jq -r ".npe.line") \ + && export BUGGY_MTHD=$(cat metadata.json | jq -r ".npe.npe_method") \ + && mv /tmp/buggy.java $BUGGY_PATH \ + && echo "[{\"filepath\": \"$BUGGY_PATH\", \"line\": $BUGGY_LINE, \"method_name\": \"$BUGGY_MTHD\"}]" | jq . > traces.json + +RUN git init . && git add -A + +RUN $(cat metadata.json | jq -r ".buildCommand") + +RUN $(cat metadata.json | jq -r ".testCommand"); if [ $? -eq 0 ]; then exit 1; fi diff --git a/Java/commons-lang-EnumUtils_113/buggy.java b/Java/commons-lang-EnumUtils_113/buggy.java new file mode 100644 index 000000000..7d5e025f2 --- /dev/null +++ b/Java/commons-lang-EnumUtils_113/buggy.java @@ -0,0 +1,324 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.lang3; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.EnumSet; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +/** + *
Utility library to provide helper methods for Java enums.
+ * + *#ThreadSafe#
+ * + * @since 3.0 + */ +public class EnumUtils { + + private static final String NULL_ELEMENTS_NOT_PERMITTED = "null elements not permitted"; + private static final String CANNOT_STORE_S_S_VALUES_IN_S_BITS = "Cannot store %s %s values in %s bits"; + private static final String S_DOES_NOT_SEEM_TO_BE_AN_ENUM_TYPE = "%s does not seem to be an Enum type"; + private static final String ENUM_CLASS_MUST_BE_DEFINED = "EnumClass must be defined."; + + /** + * This constructor is public to permit tools that require a JavaBean + * instance to operate. + */ + public EnumUtils() { + } + + /** + *Gets the {@code Map} of enums by name.
+ * + *This method is useful when you need a map of enums by name.
+ * + * @paramGets the {@code List} of enums.
+ * + *This method is useful when you need a list of enums rather than an array.
+ * + * @paramChecks if the specified name is a valid enum for the class.
+ * + *This method differs from {@link Enum#valueOf} in that checks if the name is + * a valid enum without needing to catch the exception.
+ * + * @paramGets the enum for the class, returning {@code null} if not found.
+ * + *This method differs from {@link Enum#valueOf} in that it does not throw an exception + * for an invalid enum name.
+ * + * @paramGets the enum for the class, returning {@code null} if not found.
+ * + *This method differs from {@link Enum#valueOf} in that it does not throw an exception + * for an invalid enum name.
+ * + * @paramCreates a long bit vector representation of the given subset of an Enum.
+ * + *This generates a value that is usable by {@link EnumUtils#processBitVector}.
+ * + *Do not use this method if you have more than 64 values in your Enum, as this + * would create a value greater than a long can hold.
+ * + * @param enumClass the class of the enum we are working with, not {@code null} + * @param values the values we want to convert, not {@code null}, neither containing {@code null} + * @paramCreates a bit vector representation of the given subset of an Enum using as many {@code long}s as needed.
+ * + *This generates a value that is usable by {@link EnumUtils#processBitVectors}.
+ * + *Use this method if you have more than 64 values in your Enum.
+ * + * @param enumClass the class of the enum we are working with, not {@code null} + * @param values the values we want to convert, not {@code null}, neither containing {@code null} + * @paramCreates a long bit vector representation of the given array of Enum values.
+ * + *This generates a value that is usable by {@link EnumUtils#processBitVector}.
+ * + *Do not use this method if you have more than 64 values in your Enum, as this + * would create a value greater than a long can hold.
+ * + * @param enumClass the class of the enum we are working with, not {@code null} + * @param values the values we want to convert, not {@code null} + * @paramCreates a bit vector representation of the given subset of an Enum using as many {@code long}s as needed.
+ * + *This generates a value that is usable by {@link EnumUtils#processBitVectors}.
+ * + *Use this method if you have more than 64 values in your Enum.
+ * + * @param enumClass the class of the enum we are working with, not {@code null} + * @param values the values we want to convert, not {@code null}, neither containing {@code null} + * @paramConvert a long value created by {@link EnumUtils#generateBitVector} into the set of + * enum values that it represents.
+ * + *If you store this value, beware any changes to the enum that would affect ordinal values.
+ * @param enumClass the class of the enum we are working with, not {@code null} + * @param value the long value representation of a set of enum values + * @paramConvert a {@code long[]} created by {@link EnumUtils#generateBitVectors} into the set of + * enum values that it represents.
+ * + *If you store this value, beware any changes to the enum that would affect ordinal values.
+ * @param enumClass the class of the enum we are working with, not {@code null} + * @param values the long[] bearing the representation of a set of enum values, least significant digits rightmost, not {@code null} + * @paramUtility library to provide helper methods for Java enums.
+ * + *#ThreadSafe#
+ * + * @since 3.0 + */ +public class EnumUtils { + + private static final String NULL_ELEMENTS_NOT_PERMITTED = "null elements not permitted"; + private static final String CANNOT_STORE_S_S_VALUES_IN_S_BITS = "Cannot store %s %s values in %s bits"; + private static final String S_DOES_NOT_SEEM_TO_BE_AN_ENUM_TYPE = "%s does not seem to be an Enum type"; + private static final String ENUM_CLASS_MUST_BE_DEFINED = "EnumClass must be defined."; + + /** + * This constructor is public to permit tools that require a JavaBean + * instance to operate. + */ + public EnumUtils() { + } + + /** + *Gets the {@code Map} of enums by name.
+ * + *This method is useful when you need a map of enums by name.
+ * + * @paramGets the {@code List} of enums.
+ * + *This method is useful when you need a list of enums rather than an array.
+ * + * @paramChecks if the specified name is a valid enum for the class.
+ * + *This method differs from {@link Enum#valueOf} in that checks if the name is + * a valid enum without needing to catch the exception.
+ * + * @paramChecks if the specified name is a valid enum for the class.
+ * + *This method differs from {@link Enum#valueOf} in that checks if the name is + * a valid enum without needing to catch the exception.
+ * + * @paramGets the enum for the class, returning {@code null} if not found.
+ * + *This method differs from {@link Enum#valueOf} in that it does not throw an exception + * for an invalid enum name.
+ * + * @paramCreates a long bit vector representation of the given subset of an Enum.
+ * + *This generates a value that is usable by {@link EnumUtils#processBitVector}.
+ * + *Do not use this method if you have more than 64 values in your Enum, as this + * would create a value greater than a long can hold.
+ * + * @param enumClass the class of the enum we are working with, not {@code null} + * @param values the values we want to convert, not {@code null}, neither containing {@code null} + * @paramCreates a bit vector representation of the given subset of an Enum using as many {@code long}s as needed.
+ * + *This generates a value that is usable by {@link EnumUtils#processBitVectors}.
+ * + *Use this method if you have more than 64 values in your Enum.
+ * + * @param enumClass the class of the enum we are working with, not {@code null} + * @param values the values we want to convert, not {@code null}, neither containing {@code null} + * @paramCreates a long bit vector representation of the given array of Enum values.
+ * + *This generates a value that is usable by {@link EnumUtils#processBitVector}.
+ * + *Do not use this method if you have more than 64 values in your Enum, as this + * would create a value greater than a long can hold.
+ * + * @param enumClass the class of the enum we are working with, not {@code null} + * @param values the values we want to convert, not {@code null} + * @paramCreates a bit vector representation of the given subset of an Enum using as many {@code long}s as needed.
+ * + *This generates a value that is usable by {@link EnumUtils#processBitVectors}.
+ * + *Use this method if you have more than 64 values in your Enum.
+ * + * @param enumClass the class of the enum we are working with, not {@code null} + * @param values the values we want to convert, not {@code null}, neither containing {@code null} + * @paramConvert a long value created by {@link EnumUtils#generateBitVector} into the set of + * enum values that it represents.
+ * + *If you store this value, beware any changes to the enum that would affect ordinal values.
+ * @param enumClass the class of the enum we are working with, not {@code null} + * @param value the long value representation of a set of enum values + * @paramConvert a {@code long[]} created by {@link EnumUtils#generateBitVectors} into the set of + * enum values that it represents.
+ * + *If you store this value, beware any changes to the enum that would affect ordinal values.
+ * @param enumClass the class of the enum we are working with, not {@code null} + * @param values the long[] bearing the representation of a set of enum values, least significant digits rightmost, not {@code null} + * @paramProvides utilities for manipulating and examining
+ * Throwable
objects.
Used when printing stack frames to denote the start of a + * wrapped exception.
+ * + *Package private for accessibility by test suite.
+ */ + static final String WRAPPED_MARKER = " [wrapped] "; + + /** + *The names of methods commonly used to access a wrapped exception.
+ */ + // TODO: Remove in Lang 4.0 + private static final String[] CAUSE_METHOD_NAMES = { + "getCause", + "getNextException", + "getTargetException", + "getException", + "getSourceException", + "getRootCause", + "getCausedByException", + "getNested", + "getLinkedException", + "getNestedException", + "getLinkedCause", + "getThrowable", + }; + + /** + *
+ * Public constructor allows an instance of ExceptionUtils
to be created, although that is not
+ * normally necessary.
+ *
Returns the default names used when searching for the cause of an exception.
+ * + *This may be modified and used in the overloaded getCause(Throwable, String[]) method.
+ * + * @return cloned array of the default method names + * @since 3.0 + * @deprecated This feature will be removed in Lang 4.0 + */ + @Deprecated + public static String[] getDefaultCauseMethodNames() { + return ArrayUtils.clone(CAUSE_METHOD_NAMES); + } + + //----------------------------------------------------------------------- + /** + *Introspects the Throwable
to obtain the cause.
The method searches for methods with specific names that return a
+ * Throwable
object. This will pick up most wrapping exceptions,
+ * including those from JDK 1.4.
+ *
+ *
The default list searched for are:
+ *getCause()
getNextException()
getTargetException()
getException()
getSourceException()
getRootCause()
getCausedByException()
getNested()
If none of the above is found, returns null
.
Throwable
,
+ * null
if none found or null throwable input
+ * @since 1.0
+ * @deprecated This feature will be removed in Lang 4.0, use {@link Throwable#getCause} instead
+ */
+ @Deprecated
+ public static Throwable getCause(final Throwable throwable) {
+ return getCause(throwable, null);
+ }
+
+ /**
+ * Introspects the Throwable
to obtain the cause.
A null
set of method names means use the default set.
+ * A null
in the set of method names will be ignored.
Throwable
,
+ * null
if none found or null throwable input
+ * @since 1.0
+ * @deprecated This feature will be removed in Lang 4.0, use {@link Throwable#getCause} instead
+ */
+ @Deprecated
+/**
+ * Introspects the Throwable
to obtain the cause.
A null
set of method names means use the default set.
+ * A null
in the set of method names will be ignored.
Throwable
,
+null
if none found or null throwable input
+ * @since 1.0
+ * @deprecated This feature will be removed in Lang 4.0, use {@link Throwable#getCause} instead
+ */
+public static java.lang.Throwable getCause(final java.lang.Throwable throwable, java.lang.String[] methodNames) {
+ {
+ if (methodNames == null) {
+ final java.lang.Throwable cause = /* NPEX_NULL_EXP */
+ throwable.getCause();
+ if (cause != null) {
+ return cause;
+ }
+ methodNames = org.apache.commons.lang3.exception.ExceptionUtils.CAUSE_METHOD_NAMES;
+ }
+ for (final java.lang.String methodName : methodNames) {
+ if (methodName != null) {
+ final java.lang.Throwable legacyCause = org.apache.commons.lang3.exception.ExceptionUtils.getCauseUsingMethodName(throwable, methodName);
+ if (legacyCause != null) {
+ return legacyCause;
+ }
+ }
+ }
+ return null;
+ }
+}
+
+ /**
+ * Introspects the Throwable
to obtain the root cause.
This method walks through the exception chain to the last element, + * "root" of the tree, using {@link #getCause(Throwable)}, and + * returns that exception.
+ * + *From version 2.2, this method handles recursive cause structures + * that might otherwise cause infinite loops. If the throwable parameter + * has a cause of itself, then null will be returned. If the throwable + * parameter cause chain loops, the last element in the chain before the + * loop is returned.
+ * + * @param throwable the throwable to get the root cause for, may be null + * @return the root cause of theThrowable
,
+ * null
if none found or null throwable input
+ */
+ public static Throwable getRootCause(final Throwable throwable) {
+ final ListFinds a Throwable
by method name.
null
if not found
+ */
+ // TODO: Remove in Lang 4.0
+ private static Throwable getCauseUsingMethodName(final Throwable throwable, final String methodName) {
+ Method method = null;
+ try {
+ method = throwable.getClass().getMethod(methodName);
+ } catch (final NoSuchMethodException ignored) { // NOPMD
+ // exception ignored
+ } catch (final SecurityException ignored) { // NOPMD
+ // exception ignored
+ }
+
+ if (method != null && Throwable.class.isAssignableFrom(method.getReturnType())) {
+ try {
+ return (Throwable) method.invoke(throwable);
+ } catch (final IllegalAccessException ignored) { // NOPMD
+ // exception ignored
+ } catch (final IllegalArgumentException ignored) { // NOPMD
+ // exception ignored
+ } catch (final InvocationTargetException ignored) { // NOPMD
+ // exception ignored
+ }
+ }
+ return null;
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Counts the number of Throwable
objects in the
+ * exception chain.
A throwable without cause will return 1
.
+ * A throwable with one cause will return 2
and so on.
+ * A null
throwable will return 0
.
From version 2.2, this method handles recursive cause structures + * that might otherwise cause infinite loops. The cause chain is + * processed until the end is reached, or until the next item in the + * chain is already in the result set.
+ * + * @param throwable the throwable to inspect, may be null + * @return the count of throwables, zero if null input + */ + public static int getThrowableCount(final Throwable throwable) { + return getThrowableList(throwable).size(); + } + + /** + *Returns the list of Throwable
objects in the
+ * exception chain.
A throwable without cause will return an array containing
+ * one element - the input throwable.
+ * A throwable with one cause will return an array containing
+ * two elements. - the input throwable and the cause throwable.
+ * A null
throwable will return an array of size zero.
From version 2.2, this method handles recursive cause structures + * that might otherwise cause infinite loops. The cause chain is + * processed until the end is reached, or until the next item in the + * chain is already in the result set.
+ * + * @see #getThrowableList(Throwable) + * @param throwable the throwable to inspect, may be null + * @return the array of throwables, never null + */ + public static Throwable[] getThrowables(final Throwable throwable) { + final ListReturns the list of Throwable
objects in the
+ * exception chain.
A throwable without cause will return a list containing
+ * one element - the input throwable.
+ * A throwable with one cause will return a list containing
+ * two elements. - the input throwable and the cause throwable.
+ * A null
throwable will return a list of size zero.
This method handles recursive cause structures that might + * otherwise cause infinite loops. The cause chain is processed until + * the end is reached, or until the next item in the chain is already + * in the result set.
+ * + * @param throwable the throwable to inspect, may be null + * @return the list of throwables, never null + * @since Commons Lang 2.2 + */ + public static ListReturns the (zero based) index of the first Throwable
+ * that matches the specified class (exactly) in the exception chain.
+ * Subclasses of the specified class do not match - see
+ * {@link #indexOfType(Throwable, Class)} for the opposite.
A null
throwable returns -1
.
+ * A null
type returns -1
.
+ * No match in the chain returns -1
.
Returns the (zero based) index of the first Throwable
+ * that matches the specified type in the exception chain from
+ * a specified index.
+ * Subclasses of the specified class do not match - see
+ * {@link #indexOfType(Throwable, Class, int)} for the opposite.
A null
throwable returns -1
.
+ * A null
type returns -1
.
+ * No match in the chain returns -1
.
+ * A negative start index is treated as zero.
+ * A start index greater than the number of throwables returns -1
.
Returns the (zero based) index of the first Throwable
+ * that matches the specified class or subclass in the exception chain.
+ * Subclasses of the specified class do match - see
+ * {@link #indexOfThrowable(Throwable, Class)} for the opposite.
A null
throwable returns -1
.
+ * A null
type returns -1
.
+ * No match in the chain returns -1
.
Returns the (zero based) index of the first Throwable
+ * that matches the specified type in the exception chain from
+ * a specified index.
+ * Subclasses of the specified class do match - see
+ * {@link #indexOfThrowable(Throwable, Class)} for the opposite.
A null
throwable returns -1
.
+ * A null
type returns -1
.
+ * No match in the chain returns -1
.
+ * A negative start index is treated as zero.
+ * A start index greater than the number of throwables returns -1
.
Worker method for the indexOfType
methods.
true
, compares with {@link Class#isAssignableFrom(Class)}, otherwise compares
+ * using references
+ * @return index of the type
within throwables nested within the specified throwable
+ */
+ private static int indexOf(final Throwable throwable, final Class> type, int fromIndex, final boolean subclass) {
+ if (throwable == null || type == null) {
+ return -1;
+ }
+ if (fromIndex < 0) {
+ fromIndex = 0;
+ }
+ final Throwable[] throwables = ExceptionUtils.getThrowables(throwable);
+ if (fromIndex >= throwables.length) {
+ return -1;
+ }
+ if (subclass) {
+ for (int i = fromIndex; i < throwables.length; i++) {
+ if (type.isAssignableFrom(throwables[i].getClass())) {
+ return i;
+ }
+ }
+ } else {
+ for (int i = fromIndex; i < throwables.length; i++) {
+ if (type.equals(throwables[i].getClass())) {
+ return i;
+ }
+ }
+ }
+ return -1;
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Prints a compact stack trace for the root cause of a throwable
+ * to System.err
.
The compact stack trace starts with the root cause and prints + * stack frames up to the place where it was caught and wrapped. + * Then it prints the wrapped exception and continues with stack frames + * until the wrapper exception is caught and wrapped again, etc.
+ * + *The output of this method is consistent across JDK versions. + * Note that this is the opposite order to the JDK1.4 display.
+ * + *The method is equivalent to printStackTrace
for throwables
+ * that don't have nested causes.
Prints a compact stack trace for the root cause of a throwable.
+ * + *The compact stack trace starts with the root cause and prints + * stack frames up to the place where it was caught and wrapped. + * Then it prints the wrapped exception and continues with stack frames + * until the wrapper exception is caught and wrapped again, etc.
+ * + *The output of this method is consistent across JDK versions. + * Note that this is the opposite order to the JDK1.4 display.
+ * + *The method is equivalent to printStackTrace
for throwables
+ * that don't have nested causes.
null
+ * @since 2.0
+ */
+ public static void printRootCauseStackTrace(final Throwable throwable, final PrintStream stream) {
+ if (throwable == null) {
+ return;
+ }
+ if (stream == null) {
+ throw new IllegalArgumentException("The PrintStream must not be null");
+ }
+ final String trace[] = getRootCauseStackTrace(throwable);
+ for (final String element : trace) {
+ stream.println(element);
+ }
+ stream.flush();
+ }
+
+ /**
+ * Prints a compact stack trace for the root cause of a throwable.
+ * + *The compact stack trace starts with the root cause and prints + * stack frames up to the place where it was caught and wrapped. + * Then it prints the wrapped exception and continues with stack frames + * until the wrapper exception is caught and wrapped again, etc.
+ * + *The output of this method is consistent across JDK versions. + * Note that this is the opposite order to the JDK1.4 display.
+ * + *The method is equivalent to printStackTrace
for throwables
+ * that don't have nested causes.
null
+ * @since 2.0
+ */
+ public static void printRootCauseStackTrace(final Throwable throwable, final PrintWriter writer) {
+ if (throwable == null) {
+ return;
+ }
+ if (writer == null) {
+ throw new IllegalArgumentException("The PrintWriter must not be null");
+ }
+ final String trace[] = getRootCauseStackTrace(throwable);
+ for (final String element : trace) {
+ writer.println(element);
+ }
+ writer.flush();
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Creates a compact stack trace for the root cause of the supplied
+ * Throwable
.
The output of this method is consistent across JDK versions. + * It consists of the root exception followed by each of its wrapping + * exceptions separated by '[wrapped]'. Note that this is the opposite + * order to the JDK1.4 display.
+ * + * @param throwable the throwable to examine, may be null + * @return an array of stack trace frames, never null + * @since 2.0 + */ + public static String[] getRootCauseStackTrace(final Throwable throwable) { + if (throwable == null) { + return ArrayUtils.EMPTY_STRING_ARRAY; + } + final Throwable throwables[] = getThrowables(throwable); + final int count = throwables.length; + final ListRemoves common frames from the cause trace given the two stack traces.
+ * + * @param causeFrames stack trace of a cause throwable + * @param wrapperFrames stack trace of a wrapper throwable + * @throws IllegalArgumentException if either argument is null + * @since 2.0 + */ + public static void removeCommonFrames(final ListGets the stack trace from a Throwable as a String.
+ * + *The result of this method vary by JDK version as this method + * uses {@link Throwable#printStackTrace(java.io.PrintWriter)}. + * On JDK1.3 and earlier, the cause exception will not be shown + * unless the specified throwable alters printStackTrace.
+ * + * @param throwable theThrowable
to be examined
+ * @return the stack trace as generated by the exception's
+ * printStackTrace(PrintWriter)
method
+ */
+ public static String getStackTrace(final Throwable throwable) {
+ final StringWriter sw = new StringWriter();
+ final PrintWriter pw = new PrintWriter(sw, true);
+ throwable.printStackTrace(pw);
+ return sw.getBuffer().toString();
+ }
+
+ /**
+ * Captures the stack trace associated with the specified
+ * Throwable
object, decomposing it into a list of
+ * stack frames.
The result of this method vary by JDK version as this method + * uses {@link Throwable#printStackTrace(java.io.PrintWriter)}. + * On JDK1.3 and earlier, the cause exception will not be shown + * unless the specified throwable alters printStackTrace.
+ * + * @param throwable theThrowable
to examine, may be null
+ * @return an array of strings describing each stack frame, never null
+ */
+ public static String[] getStackFrames(final Throwable throwable) {
+ if (throwable == null) {
+ return ArrayUtils.EMPTY_STRING_ARRAY;
+ }
+ return getStackFrames(getStackTrace(throwable));
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Returns an array where each element is a line from the argument.
+ * + *The end of line is determined by the value of {@link SystemUtils#LINE_SEPARATOR}.
+ * + * @param stackTrace a stack trace String + * @return an array where each element is a line from the argument + */ + static String[] getStackFrames(final String stackTrace) { + final String linebreak = SystemUtils.LINE_SEPARATOR; + final StringTokenizer frames = new StringTokenizer(stackTrace, linebreak); + final ListProduces a List
of stack frames - the message
+ * is not included. Only the trace of the specified exception is
+ * returned, any caused by trace is stripped.
This works in most cases - it will only fail if the exception
+ * message contains a line that starts with:
+ * " at".
+ * The message returned is of the form + * {ClassNameWithoutPackage}: {ThrowableMessage} + * + * @param th the throwable to get a message for, null returns empty string + * @return the message, non-null + * @since Commons Lang 2.2 + */ + public static String getMessage(final Throwable th) { + if (th == null) { + return StringUtils.EMPTY; + } + final String clsName = ClassUtils.getShortClassName(th, null); + final String msg = th.getMessage(); + return clsName + ": " + StringUtils.defaultString(msg); + } + + //----------------------------------------------------------------------- + /** + * Gets a short message summarising the root cause exception. + *
+ * The message returned is of the form + * {ClassNameWithoutPackage}: {ThrowableMessage} + * + * @param th the throwable to get a message for, null returns empty string + * @return the message, non-null + * @since Commons Lang 2.2 + */ + public static String getRootCauseMessage(final Throwable th) { + Throwable root = ExceptionUtils.getRootCause(th); + root = root == null ? th : root; + return getMessage(root); + } + + /** + * Throw a checked exception without adding the exception to the throws + * clause of the calling method. This method prevents throws clause + * pollution and reduces the clutter of "Caused by" exceptions in the + * stacktrace. + *
+ * The use of this technique may be controversial, but exceedingly useful to
+ * library developers.
+ *
+ * public int propagateExample { // note that there is no throws clause
+ * try {
+ * return invocation(); // throws IOException
+ * } catch (Exception e) {
+ * return ExceptionUtils.rethrow(e); // propagates a checked exception
+ * }
+ * }
+ *
+ *
+ * This is an alternative to the more conservative approach of wrapping the
+ * checked exception in a RuntimeException:
+ *
+ * public int wrapExample { // note that there is no throws clause
+ * try {
+ * return invocation(); // throws IOException
+ * } catch (Error e) {
+ * throw e;
+ * } catch (RuntimeException e) {
+ * throw e; // wraps a checked exception
+ * } catch (Exception e) {
+ * throw new UndeclaredThrowableException(e); // wraps a checked exception
+ * }
+ * }
+ *
+ *
+ * One downside to using this approach is that the java compiler will not
+ * allow invoking code to specify a checked exception in a catch clause
+ * unless there is some code path within the try block that has invoked a
+ * method declared with that checked exception. If the invoking site wishes
+ * to catch the shaded checked exception, it must either invoke the shaded
+ * code through a method re-declaring the desired checked exception, or
+ * catch Exception and use the instanceof operator. Either of these
+ * techniques are required when interacting with non-java jvm code such as
+ * Jyton, Scala, or Groovy, since these languages do not consider any
+ * exceptions as checked.
+ *
+ * @param throwable
+ * The throwable to rethrow.
+ * @param
+ * The downside to using this approach is that invoking code which needs to
+ * handle specific checked exceptions must sniff up the exception chain to
+ * determine if the caught exception was caused by the checked exception.
+ *
+ * @param throwable
+ * The throwable to rethrow.
+ * @param Provides utilities for manipulating and examining
+ * Used when printing stack frames to denote the start of a
+ * wrapped exception. Package private for accessibility by test suite. The names of methods commonly used to access a wrapped exception.
+ * Public constructor allows an instance of Returns the default names used when searching for the cause of an exception. This may be modified and used in the overloaded getCause(Throwable, String[]) method. Introspects the The method searches for methods with specific names that return a
+ * The default list searched for are: If none of the above is found, returns Introspects the A Introspects the A Introspects the This method walks through the exception chain to the last element,
+ * "root" of the tree, using {@link #getCause(Throwable)}, and
+ * returns that exception. From version 2.2, this method handles recursive cause structures
+ * that might otherwise cause infinite loops. If the throwable parameter
+ * has a cause of itself, then null will be returned. If the throwable
+ * parameter cause chain loops, the last element in the chain before the
+ * loop is returned. Finds a Counts the number of A throwable without cause will return From version 2.2, this method handles recursive cause structures
+ * that might otherwise cause infinite loops. The cause chain is
+ * processed until the end is reached, or until the next item in the
+ * chain is already in the result set. Returns the list of A throwable without cause will return an array containing
+ * one element - the input throwable.
+ * A throwable with one cause will return an array containing
+ * two elements. - the input throwable and the cause throwable.
+ * A From version 2.2, this method handles recursive cause structures
+ * that might otherwise cause infinite loops. The cause chain is
+ * processed until the end is reached, or until the next item in the
+ * chain is already in the result set. Returns the list of A throwable without cause will return a list containing
+ * one element - the input throwable.
+ * A throwable with one cause will return a list containing
+ * two elements. - the input throwable and the cause throwable.
+ * A This method handles recursive cause structures that might
+ * otherwise cause infinite loops. The cause chain is processed until
+ * the end is reached, or until the next item in the chain is already
+ * in the result set. Returns the (zero based) index of the first A Returns the (zero based) index of the first A Returns the (zero based) index of the first A Returns the (zero based) index of the first A Worker method for the Prints a compact stack trace for the root cause of a throwable
+ * to The compact stack trace starts with the root cause and prints
+ * stack frames up to the place where it was caught and wrapped.
+ * Then it prints the wrapped exception and continues with stack frames
+ * until the wrapper exception is caught and wrapped again, etc. The output of this method is consistent across JDK versions.
+ * Note that this is the opposite order to the JDK1.4 display. The method is equivalent to Prints a compact stack trace for the root cause of a throwable. The compact stack trace starts with the root cause and prints
+ * stack frames up to the place where it was caught and wrapped.
+ * Then it prints the wrapped exception and continues with stack frames
+ * until the wrapper exception is caught and wrapped again, etc. The output of this method is consistent across JDK versions.
+ * Note that this is the opposite order to the JDK1.4 display. The method is equivalent to Prints a compact stack trace for the root cause of a throwable. The compact stack trace starts with the root cause and prints
+ * stack frames up to the place where it was caught and wrapped.
+ * Then it prints the wrapped exception and continues with stack frames
+ * until the wrapper exception is caught and wrapped again, etc. The output of this method is consistent across JDK versions.
+ * Note that this is the opposite order to the JDK1.4 display. The method is equivalent to Creates a compact stack trace for the root cause of the supplied
+ * The output of this method is consistent across JDK versions.
+ * It consists of the root exception followed by each of its wrapping
+ * exceptions separated by '[wrapped]'. Note that this is the opposite
+ * order to the JDK1.4 display. Removes common frames from the cause trace given the two stack traces. Gets the stack trace from a Throwable as a String. The result of this method vary by JDK version as this method
+ * uses {@link Throwable#printStackTrace(java.io.PrintWriter)}.
+ * On JDK1.3 and earlier, the cause exception will not be shown
+ * unless the specified throwable alters printStackTrace. Captures the stack trace associated with the specified
+ * The result of this method vary by JDK version as this method
+ * uses {@link Throwable#printStackTrace(java.io.PrintWriter)}.
+ * On JDK1.3 and earlier, the cause exception will not be shown
+ * unless the specified throwable alters printStackTrace. Returns an array where each element is a line from the argument. The end of line is determined by the value of {@link SystemUtils#LINE_SEPARATOR}. Produces a This works in most cases - it will only fail if the exception
+ * message contains a line that starts with:
+ *
+ * The message returned is of the form
+ * {ClassNameWithoutPackage}: {ThrowableMessage}
+ *
+ * @param th the throwable to get a message for, null returns empty string
+ * @return the message, non-null
+ * @since Commons Lang 2.2
+ */
+ public static String getMessage(final Throwable th) {
+ if (th == null) {
+ return StringUtils.EMPTY;
+ }
+ final String clsName = ClassUtils.getShortClassName(th, null);
+ final String msg = th.getMessage();
+ return clsName + ": " + StringUtils.defaultString(msg);
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Gets a short message summarising the root cause exception.
+ *
+ * The message returned is of the form
+ * {ClassNameWithoutPackage}: {ThrowableMessage}
+ *
+ * @param th the throwable to get a message for, null returns empty string
+ * @return the message, non-null
+ * @since Commons Lang 2.2
+ */
+ public static String getRootCauseMessage(final Throwable th) {
+ Throwable root = ExceptionUtils.getRootCause(th);
+ root = root == null ? th : root;
+ return getMessage(root);
+ }
+
+ /**
+ * Throw a checked exception without adding the exception to the throws
+ * clause of the calling method. This method prevents throws clause
+ * pollution and reduces the clutter of "Caused by" exceptions in the
+ * stacktrace.
+ *
+ * The use of this technique may be controversial, but exceedingly useful to
+ * library developers.
+ *
+ * This is an alternative to the more conservative approach of wrapping the
+ * checked exception in a RuntimeException:
+ *
+ * One downside to using this approach is that the java compiler will not
+ * allow invoking code to specify a checked exception in a catch clause
+ * unless there is some code path within the try block that has invoked a
+ * method declared with that checked exception. If the invoking site wishes
+ * to catch the shaded checked exception, it must either invoke the shaded
+ * code through a method re-declaring the desired checked exception, or
+ * catch Exception and use the instanceof operator. Either of these
+ * techniques are required when interacting with non-java jvm code such as
+ * Jyton, Scala, or Groovy, since these languages do not consider any
+ * exceptions as checked.
+ *
+ * @param throwable
+ * The throwable to rethrow.
+ * @param
+ * The downside to using this approach is that invoking code which needs to
+ * handle specific checked exceptions must sniff up the exception chain to
+ * determine if the caught exception was caused by the checked exception.
+ *
+ * @param throwable
+ * The throwable to rethrow.
+ * @param Provides utilities for manipulating and examining
+ * Used when printing stack frames to denote the start of a
+ * wrapped exception. Package private for accessibility by test suite. The names of methods commonly used to access a wrapped exception.
+ * Public constructor allows an instance of Returns the default names used when searching for the cause of an exception. This may be modified and used in the overloaded getCause(Throwable, String[]) method. Introspects the The method searches for methods with specific names that return a
+ * The default list searched for are: If none of the above is found, returns Introspects the A Introspects the A Introspects the This method walks through the exception chain to the last element,
+ * "root" of the tree, using {@link #getCause(Throwable)}, and
+ * returns that exception. From version 2.2, this method handles recursive cause structures
+ * that might otherwise cause infinite loops. If the throwable parameter
+ * has a cause of itself, then null will be returned. If the throwable
+ * parameter cause chain loops, the last element in the chain before the
+ * loop is returned. Finds a Counts the number of A throwable without cause will return From version 2.2, this method handles recursive cause structures
+ * that might otherwise cause infinite loops. The cause chain is
+ * processed until the end is reached, or until the next item in the
+ * chain is already in the result set. Returns the list of A throwable without cause will return an array containing
+ * one element - the input throwable.
+ * A throwable with one cause will return an array containing
+ * two elements. - the input throwable and the cause throwable.
+ * A From version 2.2, this method handles recursive cause structures
+ * that might otherwise cause infinite loops. The cause chain is
+ * processed until the end is reached, or until the next item in the
+ * chain is already in the result set. Returns the list of A throwable without cause will return a list containing
+ * one element - the input throwable.
+ * A throwable with one cause will return a list containing
+ * two elements. - the input throwable and the cause throwable.
+ * A This method handles recursive cause structures that might
+ * otherwise cause infinite loops. The cause chain is processed until
+ * the end is reached, or until the next item in the chain is already
+ * in the result set. Returns the (zero based) index of the first A Returns the (zero based) index of the first A Returns the (zero based) index of the first A Returns the (zero based) index of the first A Worker method for the Prints a compact stack trace for the root cause of a throwable
+ * to The compact stack trace starts with the root cause and prints
+ * stack frames up to the place where it was caught and wrapped.
+ * Then it prints the wrapped exception and continues with stack frames
+ * until the wrapper exception is caught and wrapped again, etc. The output of this method is consistent across JDK versions.
+ * Note that this is the opposite order to the JDK1.4 display. The method is equivalent to Prints a compact stack trace for the root cause of a throwable. The compact stack trace starts with the root cause and prints
+ * stack frames up to the place where it was caught and wrapped.
+ * Then it prints the wrapped exception and continues with stack frames
+ * until the wrapper exception is caught and wrapped again, etc. The output of this method is consistent across JDK versions.
+ * Note that this is the opposite order to the JDK1.4 display. The method is equivalent to Prints a compact stack trace for the root cause of a throwable. The compact stack trace starts with the root cause and prints
+ * stack frames up to the place where it was caught and wrapped.
+ * Then it prints the wrapped exception and continues with stack frames
+ * until the wrapper exception is caught and wrapped again, etc. The output of this method is consistent across JDK versions.
+ * Note that this is the opposite order to the JDK1.4 display. The method is equivalent to Creates a compact stack trace for the root cause of the supplied
+ * The output of this method is consistent across JDK versions.
+ * It consists of the root exception followed by each of its wrapping
+ * exceptions separated by '[wrapped]'. Note that this is the opposite
+ * order to the JDK1.4 display. Removes common frames from the cause trace given the two stack traces. Gets the stack trace from a Throwable as a String. The result of this method vary by JDK version as this method
+ * uses {@link Throwable#printStackTrace(java.io.PrintWriter)}.
+ * On JDK1.3 and earlier, the cause exception will not be shown
+ * unless the specified throwable alters printStackTrace. Captures the stack trace associated with the specified
+ * The result of this method vary by JDK version as this method
+ * uses {@link Throwable#printStackTrace(java.io.PrintWriter)}.
+ * On JDK1.3 and earlier, the cause exception will not be shown
+ * unless the specified throwable alters printStackTrace. Returns an array where each element is a line from the argument. The end of line is determined by the value of {@link SystemUtils#LINE_SEPARATOR}. Produces a This works in most cases - it will only fail if the exception
+ * message contains a line that starts with:
+ *
+ * The message returned is of the form
+ * {ClassNameWithoutPackage}: {ThrowableMessage}
+ *
+ * @param th the throwable to get a message for, null returns empty string
+ * @return the message, non-null
+ * @since Commons Lang 2.2
+ */
+ public static String getMessage(final Throwable th) {
+ if (th == null) {
+ return StringUtils.EMPTY;
+ }
+ final String clsName = ClassUtils.getShortClassName(th, null);
+ final String msg = th.getMessage();
+ return clsName + ": " + StringUtils.defaultString(msg);
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Gets a short message summarising the root cause exception.
+ *
+ * The message returned is of the form
+ * {ClassNameWithoutPackage}: {ThrowableMessage}
+ *
+ * @param th the throwable to get a message for, null returns empty string
+ * @return the message, non-null
+ * @since Commons Lang 2.2
+ */
+ public static String getRootCauseMessage(final Throwable th) {
+ Throwable root = ExceptionUtils.getRootCause(th);
+ root = root == null ? th : root;
+ return getMessage(root);
+ }
+
+ /**
+ * Throw a checked exception without adding the exception to the throws
+ * clause of the calling method. This method prevents throws clause
+ * pollution and reduces the clutter of "Caused by" exceptions in the
+ * stacktrace.
+ *
+ * The use of this technique may be controversial, but exceedingly useful to
+ * library developers.
+ *
+ * This is an alternative to the more conservative approach of wrapping the
+ * checked exception in a RuntimeException:
+ *
+ * One downside to using this approach is that the java compiler will not
+ * allow invoking code to specify a checked exception in a catch clause
+ * unless there is some code path within the try block that has invoked a
+ * method declared with that checked exception. If the invoking site wishes
+ * to catch the shaded checked exception, it must either invoke the shaded
+ * code through a method re-declaring the desired checked exception, or
+ * catch Exception and use the instanceof operator. Either of these
+ * techniques are required when interacting with non-java jvm code such as
+ * Jyton, Scala, or Groovy, since these languages do not consider any
+ * exceptions as checked.
+ *
+ * @param throwable
+ * The throwable to rethrow.
+ * @param
+ * The downside to using this approach is that invoking code which needs to
+ * handle specific checked exceptions must sniff up the exception chain to
+ * determine if the caught exception was caused by the checked exception.
+ *
+ * @param throwable
+ * The throwable to rethrow.
+ * @param Provides utilities for manipulating and examining
+ * Used when printing stack frames to denote the start of a
+ * wrapped exception. Package private for accessibility by test suite. The names of methods commonly used to access a wrapped exception.
+ * Public constructor allows an instance of Returns the default names used when searching for the cause of an exception. This may be modified and used in the overloaded getCause(Throwable, String[]) method. Introspects the The method searches for methods with specific names that return a
+ * The default list searched for are: If none of the above is found, returns Introspects the A Introspects the This method walks through the exception chain to the last element,
+ * "root" of the tree, using {@link #getCause(Throwable)}, and
+ * returns that exception. From version 2.2, this method handles recursive cause structures
+ * that might otherwise cause infinite loops. If the throwable parameter
+ * has a cause of itself, then null will be returned. If the throwable
+ * parameter cause chain loops, the last element in the chain before the
+ * loop is returned. Finds a Counts the number of A throwable without cause will return From version 2.2, this method handles recursive cause structures
+ * that might otherwise cause infinite loops. The cause chain is
+ * processed until the end is reached, or until the next item in the
+ * chain is already in the result set. Returns the list of A throwable without cause will return an array containing
+ * one element - the input throwable.
+ * A throwable with one cause will return an array containing
+ * two elements. - the input throwable and the cause throwable.
+ * A From version 2.2, this method handles recursive cause structures
+ * that might otherwise cause infinite loops. The cause chain is
+ * processed until the end is reached, or until the next item in the
+ * chain is already in the result set. Returns the list of A throwable without cause will return a list containing
+ * one element - the input throwable.
+ * A throwable with one cause will return a list containing
+ * two elements. - the input throwable and the cause throwable.
+ * A This method handles recursive cause structures that might
+ * otherwise cause infinite loops. The cause chain is processed until
+ * the end is reached, or until the next item in the chain is already
+ * in the result set. Returns the (zero based) index of the first A Returns the (zero based) index of the first A Returns the (zero based) index of the first A Returns the (zero based) index of the first A Worker method for the Prints a compact stack trace for the root cause of a throwable
+ * to The compact stack trace starts with the root cause and prints
+ * stack frames up to the place where it was caught and wrapped.
+ * Then it prints the wrapped exception and continues with stack frames
+ * until the wrapper exception is caught and wrapped again, etc. The output of this method is consistent across JDK versions.
+ * Note that this is the opposite order to the JDK1.4 display. The method is equivalent to Prints a compact stack trace for the root cause of a throwable. The compact stack trace starts with the root cause and prints
+ * stack frames up to the place where it was caught and wrapped.
+ * Then it prints the wrapped exception and continues with stack frames
+ * until the wrapper exception is caught and wrapped again, etc. The output of this method is consistent across JDK versions.
+ * Note that this is the opposite order to the JDK1.4 display. The method is equivalent to Prints a compact stack trace for the root cause of a throwable. The compact stack trace starts with the root cause and prints
+ * stack frames up to the place where it was caught and wrapped.
+ * Then it prints the wrapped exception and continues with stack frames
+ * until the wrapper exception is caught and wrapped again, etc. The output of this method is consistent across JDK versions.
+ * Note that this is the opposite order to the JDK1.4 display. The method is equivalent to Prints a compact stack trace for the root cause of a throwable. The compact stack trace starts with the root cause and prints
+ * stack frames up to the place where it was caught and wrapped.
+ * Then it prints the wrapped exception and continues with stack frames
+ * until the wrapper exception is caught and wrapped again, etc. The output of this method is consistent across JDK versions.
+ * Note that this is the opposite order to the JDK1.4 display. The method is equivalent to Creates a compact stack trace for the root cause of the supplied
+ * The output of this method is consistent across JDK versions.
+ * It consists of the root exception followed by each of its wrapping
+ * exceptions separated by '[wrapped]'. Note that this is the opposite
+ * order to the JDK1.4 display. Removes common frames from the cause trace given the two stack traces. Gets the stack trace from a Throwable as a String. The result of this method vary by JDK version as this method
+ * uses {@link Throwable#printStackTrace(java.io.PrintWriter)}.
+ * On JDK1.3 and earlier, the cause exception will not be shown
+ * unless the specified throwable alters printStackTrace. Captures the stack trace associated with the specified
+ * The result of this method vary by JDK version as this method
+ * uses {@link Throwable#printStackTrace(java.io.PrintWriter)}.
+ * On JDK1.3 and earlier, the cause exception will not be shown
+ * unless the specified throwable alters printStackTrace. Returns an array where each element is a line from the argument. The end of line is determined by the value of {@link SystemUtils#LINE_SEPARATOR}. Produces a This works in most cases - it will only fail if the exception
+ * message contains a line that starts with:
+ *
+ * The message returned is of the form
+ * {ClassNameWithoutPackage}: {ThrowableMessage}
+ *
+ * @param th the throwable to get a message for, null returns empty string
+ * @return the message, non-null
+ * @since Commons Lang 2.2
+ */
+ public static String getMessage(final Throwable th) {
+ if (th == null) {
+ return StringUtils.EMPTY;
+ }
+ final String clsName = ClassUtils.getShortClassName(th, null);
+ final String msg = th.getMessage();
+ return clsName + ": " + StringUtils.defaultString(msg);
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Gets a short message summarising the root cause exception.
+ *
+ * The message returned is of the form
+ * {ClassNameWithoutPackage}: {ThrowableMessage}
+ *
+ * @param th the throwable to get a message for, null returns empty string
+ * @return the message, non-null
+ * @since Commons Lang 2.2
+ */
+ public static String getRootCauseMessage(final Throwable th) {
+ Throwable root = ExceptionUtils.getRootCause(th);
+ root = root == null ? th : root;
+ return getMessage(root);
+ }
+
+ /**
+ * Throw a checked exception without adding the exception to the throws
+ * clause of the calling method. This method prevents throws clause
+ * pollution and reduces the clutter of "Caused by" exceptions in the
+ * stacktrace.
+ *
+ * The use of this technique may be controversial, but exceedingly useful to
+ * library developers.
+ *
+ * This is an alternative to the more conservative approach of wrapping the
+ * checked exception in a RuntimeException:
+ *
+ * One downside to using this approach is that the java compiler will not
+ * allow invoking code to specify a checked exception in a catch clause
+ * unless there is some code path within the try block that has invoked a
+ * method declared with that checked exception. If the invoking site wishes
+ * to catch the shaded checked exception, it must either invoke the shaded
+ * code through a method re-declaring the desired checked exception, or
+ * catch Exception and use the instanceof operator. Either of these
+ * techniques are required when interacting with non-java jvm code such as
+ * Jyton, Scala, or Groovy, since these languages do not consider any
+ * exceptions as checked.
+ *
+ * @param throwable
+ * The throwable to rethrow.
+ * @param
+ * The downside to using this approach is that invoking code which needs to
+ * handle specific checked exceptions must sniff up the exception chain to
+ * determine if the caught exception was caused by the checked exception.
+ *
+ * @param throwable
+ * The throwable to rethrow.
+ * @param Provides utilities for manipulating and examining
+ * Used when printing stack frames to denote the start of a
+ * wrapped exception. Package private for accessibility by test suite. The names of methods commonly used to access a wrapped exception.
+ * Public constructor allows an instance of Returns the default names used when searching for the cause of an exception. This may be modified and used in the overloaded getCause(Throwable, String[]) method. Introspects the The method searches for methods with specific names that return a
+ * The default list searched for are: If none of the above is found, returns Introspects the A Introspects the This method walks through the exception chain to the last element,
+ * "root" of the tree, using {@link #getCause(Throwable)}, and
+ * returns that exception. From version 2.2, this method handles recursive cause structures
+ * that might otherwise cause infinite loops. If the throwable parameter
+ * has a cause of itself, then null will be returned. If the throwable
+ * parameter cause chain loops, the last element in the chain before the
+ * loop is returned. Finds a Counts the number of A throwable without cause will return From version 2.2, this method handles recursive cause structures
+ * that might otherwise cause infinite loops. The cause chain is
+ * processed until the end is reached, or until the next item in the
+ * chain is already in the result set. Returns the list of A throwable without cause will return an array containing
+ * one element - the input throwable.
+ * A throwable with one cause will return an array containing
+ * two elements. - the input throwable and the cause throwable.
+ * A From version 2.2, this method handles recursive cause structures
+ * that might otherwise cause infinite loops. The cause chain is
+ * processed until the end is reached, or until the next item in the
+ * chain is already in the result set. Returns the list of A throwable without cause will return a list containing
+ * one element - the input throwable.
+ * A throwable with one cause will return a list containing
+ * two elements. - the input throwable and the cause throwable.
+ * A This method handles recursive cause structures that might
+ * otherwise cause infinite loops. The cause chain is processed until
+ * the end is reached, or until the next item in the chain is already
+ * in the result set. Returns the (zero based) index of the first A Returns the (zero based) index of the first A Returns the (zero based) index of the first A Returns the (zero based) index of the first A Worker method for the Prints a compact stack trace for the root cause of a throwable
+ * to The compact stack trace starts with the root cause and prints
+ * stack frames up to the place where it was caught and wrapped.
+ * Then it prints the wrapped exception and continues with stack frames
+ * until the wrapper exception is caught and wrapped again, etc. The output of this method is consistent across JDK versions.
+ * Note that this is the opposite order to the JDK1.4 display. The method is equivalent to Prints a compact stack trace for the root cause of a throwable. The compact stack trace starts with the root cause and prints
+ * stack frames up to the place where it was caught and wrapped.
+ * Then it prints the wrapped exception and continues with stack frames
+ * until the wrapper exception is caught and wrapped again, etc. The output of this method is consistent across JDK versions.
+ * Note that this is the opposite order to the JDK1.4 display. The method is equivalent to Prints a compact stack trace for the root cause of a throwable. The compact stack trace starts with the root cause and prints
+ * stack frames up to the place where it was caught and wrapped.
+ * Then it prints the wrapped exception and continues with stack frames
+ * until the wrapper exception is caught and wrapped again, etc. The output of this method is consistent across JDK versions.
+ * Note that this is the opposite order to the JDK1.4 display. The method is equivalent to Prints a compact stack trace for the root cause of a throwable. The compact stack trace starts with the root cause and prints
+ * stack frames up to the place where it was caught and wrapped.
+ * Then it prints the wrapped exception and continues with stack frames
+ * until the wrapper exception is caught and wrapped again, etc. The output of this method is consistent across JDK versions.
+ * Note that this is the opposite order to the JDK1.4 display. The method is equivalent to Creates a compact stack trace for the root cause of the supplied
+ * The output of this method is consistent across JDK versions.
+ * It consists of the root exception followed by each of its wrapping
+ * exceptions separated by '[wrapped]'. Note that this is the opposite
+ * order to the JDK1.4 display. Removes common frames from the cause trace given the two stack traces. Gets the stack trace from a Throwable as a String. The result of this method vary by JDK version as this method
+ * uses {@link Throwable#printStackTrace(java.io.PrintWriter)}.
+ * On JDK1.3 and earlier, the cause exception will not be shown
+ * unless the specified throwable alters printStackTrace. Captures the stack trace associated with the specified
+ * The result of this method vary by JDK version as this method
+ * uses {@link Throwable#printStackTrace(java.io.PrintWriter)}.
+ * On JDK1.3 and earlier, the cause exception will not be shown
+ * unless the specified throwable alters printStackTrace. Returns an array where each element is a line from the argument. The end of line is determined by the value of {@link SystemUtils#LINE_SEPARATOR}. Produces a This works in most cases - it will only fail if the exception
+ * message contains a line that starts with:
+ *
+ * The message returned is of the form
+ * {ClassNameWithoutPackage}: {ThrowableMessage}
+ *
+ * @param th the throwable to get a message for, null returns empty string
+ * @return the message, non-null
+ * @since Commons Lang 2.2
+ */
+ public static String getMessage(final Throwable th) {
+ if (th == null) {
+ return StringUtils.EMPTY;
+ }
+ final String clsName = ClassUtils.getShortClassName(th, null);
+ final String msg = th.getMessage();
+ return clsName + ": " + StringUtils.defaultString(msg);
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Gets a short message summarising the root cause exception.
+ *
+ * The message returned is of the form
+ * {ClassNameWithoutPackage}: {ThrowableMessage}
+ *
+ * @param th the throwable to get a message for, null returns empty string
+ * @return the message, non-null
+ * @since Commons Lang 2.2
+ */
+ public static String getRootCauseMessage(final Throwable th) {
+ Throwable root = ExceptionUtils.getRootCause(th);
+ root = root == null ? th : root;
+ return getMessage(root);
+ }
+
+ /**
+ * Throw a checked exception without adding the exception to the throws
+ * clause of the calling method. This method prevents throws clause
+ * pollution and reduces the clutter of "Caused by" exceptions in the
+ * stacktrace.
+ *
+ * The use of this technique may be controversial, but exceedingly useful to
+ * library developers.
+ *
+ * This is an alternative to the more conservative approach of wrapping the
+ * checked exception in a RuntimeException:
+ *
+ * One downside to using this approach is that the java compiler will not
+ * allow invoking code to specify a checked exception in a catch clause
+ * unless there is some code path within the try block that has invoked a
+ * method declared with that checked exception. If the invoking site wishes
+ * to catch the shaded checked exception, it must either invoke the shaded
+ * code through a method re-declaring the desired checked exception, or
+ * catch Exception and use the instanceof operator. Either of these
+ * techniques are required when interacting with non-java jvm code such as
+ * Jyton, Scala, or Groovy, since these languages do not consider any
+ * exceptions as checked.
+ *
+ * @param throwable
+ * The throwable to rethrow.
+ * @param
+ * The downside to using this approach is that invoking code which needs to
+ * handle specific checked exceptions must sniff up the exception chain to
+ * determine if the caught exception was caused by the checked exception.
+ *
+ * @param throwable
+ * The throwable to rethrow.
+ * @param Provides utilities for manipulating and examining
+ * Used when printing stack frames to denote the start of a
+ * wrapped exception. Package private for accessibility by test suite. The names of methods commonly used to access a wrapped exception.
+ * Public constructor allows an instance of Returns the default names used when searching for the cause of an exception. This may be modified and used in the overloaded getCause(Throwable, String[]) method. Introspects the The method searches for methods with specific names that return a
+ * The default list searched for are: If none of the above is found, returns Introspects the A Introspects the This method walks through the exception chain to the last element,
+ * "root" of the tree, using {@link #getCause(Throwable)}, and
+ * returns that exception. From version 2.2, this method handles recursive cause structures
+ * that might otherwise cause infinite loops. If the throwable parameter
+ * has a cause of itself, then null will be returned. If the throwable
+ * parameter cause chain loops, the last element in the chain before the
+ * loop is returned. Finds a Counts the number of A throwable without cause will return From version 2.2, this method handles recursive cause structures
+ * that might otherwise cause infinite loops. The cause chain is
+ * processed until the end is reached, or until the next item in the
+ * chain is already in the result set. Returns the list of A throwable without cause will return an array containing
+ * one element - the input throwable.
+ * A throwable with one cause will return an array containing
+ * two elements. - the input throwable and the cause throwable.
+ * A From version 2.2, this method handles recursive cause structures
+ * that might otherwise cause infinite loops. The cause chain is
+ * processed until the end is reached, or until the next item in the
+ * chain is already in the result set. Returns the list of A throwable without cause will return a list containing
+ * one element - the input throwable.
+ * A throwable with one cause will return a list containing
+ * two elements. - the input throwable and the cause throwable.
+ * A This method handles recursive cause structures that might
+ * otherwise cause infinite loops. The cause chain is processed until
+ * the end is reached, or until the next item in the chain is already
+ * in the result set. Returns the (zero based) index of the first A Returns the (zero based) index of the first A Returns the (zero based) index of the first A Returns the (zero based) index of the first A Worker method for the Prints a compact stack trace for the root cause of a throwable
+ * to The compact stack trace starts with the root cause and prints
+ * stack frames up to the place where it was caught and wrapped.
+ * Then it prints the wrapped exception and continues with stack frames
+ * until the wrapper exception is caught and wrapped again, etc. The output of this method is consistent across JDK versions.
+ * Note that this is the opposite order to the JDK1.4 display. The method is equivalent to Prints a compact stack trace for the root cause of a throwable. The compact stack trace starts with the root cause and prints
+ * stack frames up to the place where it was caught and wrapped.
+ * Then it prints the wrapped exception and continues with stack frames
+ * until the wrapper exception is caught and wrapped again, etc. The output of this method is consistent across JDK versions.
+ * Note that this is the opposite order to the JDK1.4 display. The method is equivalent to Prints a compact stack trace for the root cause of a throwable. The compact stack trace starts with the root cause and prints
+ * stack frames up to the place where it was caught and wrapped.
+ * Then it prints the wrapped exception and continues with stack frames
+ * until the wrapper exception is caught and wrapped again, etc. The output of this method is consistent across JDK versions.
+ * Note that this is the opposite order to the JDK1.4 display. The method is equivalent to Prints a compact stack trace for the root cause of a throwable. The compact stack trace starts with the root cause and prints
+ * stack frames up to the place where it was caught and wrapped.
+ * Then it prints the wrapped exception and continues with stack frames
+ * until the wrapper exception is caught and wrapped again, etc. The output of this method is consistent across JDK versions.
+ * Note that this is the opposite order to the JDK1.4 display. The method is equivalent to Creates a compact stack trace for the root cause of the supplied
+ * The output of this method is consistent across JDK versions.
+ * It consists of the root exception followed by each of its wrapping
+ * exceptions separated by '[wrapped]'. Note that this is the opposite
+ * order to the JDK1.4 display. Removes common frames from the cause trace given the two stack traces. Gets the stack trace from a Throwable as a String. The result of this method vary by JDK version as this method
+ * uses {@link Throwable#printStackTrace(java.io.PrintWriter)}.
+ * On JDK1.3 and earlier, the cause exception will not be shown
+ * unless the specified throwable alters printStackTrace. Captures the stack trace associated with the specified
+ * The result of this method vary by JDK version as this method
+ * uses {@link Throwable#printStackTrace(java.io.PrintWriter)}.
+ * On JDK1.3 and earlier, the cause exception will not be shown
+ * unless the specified throwable alters printStackTrace. Returns an array where each element is a line from the argument. The end of line is determined by the value of {@link SystemUtils#LINE_SEPARATOR}. Produces a This works in most cases - it will only fail if the exception
+ * message contains a line that starts with:
+ *
+ * The message returned is of the form
+ * {ClassNameWithoutPackage}: {ThrowableMessage}
+ *
+ * @param th the throwable to get a message for, null returns empty string
+ * @return the message, non-null
+ * @since Commons Lang 2.2
+ */
+ public static String getMessage(final Throwable th) {
+ if (th == null) {
+ return StringUtils.EMPTY;
+ }
+ final String clsName = ClassUtils.getShortClassName(th, null);
+ final String msg = th.getMessage();
+ return clsName + ": " + StringUtils.defaultString(msg);
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Gets a short message summarising the root cause exception.
+ *
+ * The message returned is of the form
+ * {ClassNameWithoutPackage}: {ThrowableMessage}
+ *
+ * @param th the throwable to get a message for, null returns empty string
+ * @return the message, non-null
+ * @since Commons Lang 2.2
+ */
+ public static String getRootCauseMessage(final Throwable th) {
+ Throwable root = ExceptionUtils.getRootCause(th);
+ root = root == null ? th : root;
+ return getMessage(root);
+ }
+
+ /**
+ * Throw a checked exception without adding the exception to the throws
+ * clause of the calling method. This method prevents throws clause
+ * pollution and reduces the clutter of "Caused by" exceptions in the
+ * stacktrace.
+ *
+ * The use of this technique may be controversial, but exceedingly useful to
+ * library developers.
+ * Throwable
objects.ExceptionUtils
to be created, although that is not
+ * normally necessary.
+ * Throwable
to obtain the cause.Throwable
object. This will pick up most wrapping exceptions,
+ * including those from JDK 1.4.
+ *
+ *
+ *
+ *
+ * getCause()
getNextException()
getTargetException()
getException()
getSourceException()
getRootCause()
getCausedByException()
getNested()
null
.Throwable
,
+ * null
if none found or null throwable input
+ * @since 1.0
+ * @deprecated This feature will be removed in Lang 4.0, use {@link Throwable#getCause} instead
+ */
+ @Deprecated
+ public static Throwable getCause(final Throwable throwable) {
+ return getCause(throwable, null);
+ }
+
+ /**
+ * Throwable
to obtain the cause.null
set of method names means use the default set.
+ * A null
in the set of method names will be ignored.Throwable
,
+ * null
if none found or null throwable input
+ * @since 1.0
+ * @deprecated This feature will be removed in Lang 4.0, use {@link Throwable#getCause} instead
+ */
+ @Deprecated
+/**
+ * Throwable
to obtain the cause.null
set of method names means use the default set.
+ * A null
in the set of method names will be ignored.Throwable
,
+null
if none found or null throwable input
+ * @since 1.0
+ * @deprecated This feature will be removed in Lang 4.0, use {@link Throwable#getCause} instead
+ */
+public static java.lang.Throwable getCause(final java.lang.Throwable throwable, java.lang.String[] methodNames) {
+ if (throwable == null) {
+ return null;
+ }
+ if (methodNames == null) {
+ final java.lang.Throwable cause = throwable.getCause();
+ if (cause != null) {
+ return cause;
+ }
+ methodNames = org.apache.commons.lang3.exception.ExceptionUtils.CAUSE_METHOD_NAMES;
+ }
+ for (final java.lang.String methodName : methodNames) {
+ {
+ final java.lang.Throwable legacyCause = org.apache.commons.lang3.exception.ExceptionUtils.getCauseUsingMethodName(throwable, /* NPEX_NULL_EXP */
+ methodName);
+ if (legacyCause != null) {
+ return legacyCause;
+ }
+ }
+ }
+ return null;
+}
+
+ /**
+ * Throwable
to obtain the root cause.Throwable
,
+ * null
if none found or null throwable input
+ */
+ public static Throwable getRootCause(final Throwable throwable) {
+ final ListThrowable
by method name.null
if not found
+ */
+ // TODO: Remove in Lang 4.0
+ private static Throwable getCauseUsingMethodName(final Throwable throwable, final String methodName) {
+ Method method = null;
+ try {
+ method = throwable.getClass().getMethod(methodName);
+ } catch (final NoSuchMethodException ignored) { // NOPMD
+ // exception ignored
+ } catch (final SecurityException ignored) { // NOPMD
+ // exception ignored
+ }
+
+ if (method != null && Throwable.class.isAssignableFrom(method.getReturnType())) {
+ try {
+ return (Throwable) method.invoke(throwable);
+ } catch (final IllegalAccessException ignored) { // NOPMD
+ // exception ignored
+ } catch (final IllegalArgumentException ignored) { // NOPMD
+ // exception ignored
+ } catch (final InvocationTargetException ignored) { // NOPMD
+ // exception ignored
+ }
+ }
+ return null;
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Throwable
objects in the
+ * exception chain.1
.
+ * A throwable with one cause will return 2
and so on.
+ * A null
throwable will return 0
.Throwable
objects in the
+ * exception chain.null
throwable will return an array of size zero.Throwable
objects in the
+ * exception chain.null
throwable will return a list of size zero.Throwable
+ * that matches the specified class (exactly) in the exception chain.
+ * Subclasses of the specified class do not match - see
+ * {@link #indexOfType(Throwable, Class)} for the opposite.null
throwable returns -1
.
+ * A null
type returns -1
.
+ * No match in the chain returns -1
.Throwable
+ * that matches the specified type in the exception chain from
+ * a specified index.
+ * Subclasses of the specified class do not match - see
+ * {@link #indexOfType(Throwable, Class, int)} for the opposite.null
throwable returns -1
.
+ * A null
type returns -1
.
+ * No match in the chain returns -1
.
+ * A negative start index is treated as zero.
+ * A start index greater than the number of throwables returns -1
.Throwable
+ * that matches the specified class or subclass in the exception chain.
+ * Subclasses of the specified class do match - see
+ * {@link #indexOfThrowable(Throwable, Class)} for the opposite.null
throwable returns -1
.
+ * A null
type returns -1
.
+ * No match in the chain returns -1
.Throwable
+ * that matches the specified type in the exception chain from
+ * a specified index.
+ * Subclasses of the specified class do match - see
+ * {@link #indexOfThrowable(Throwable, Class)} for the opposite.null
throwable returns -1
.
+ * A null
type returns -1
.
+ * No match in the chain returns -1
.
+ * A negative start index is treated as zero.
+ * A start index greater than the number of throwables returns -1
.indexOfType
methods.true
, compares with {@link Class#isAssignableFrom(Class)}, otherwise compares
+ * using references
+ * @return index of the type
within throwables nested within the specified throwable
+ */
+ private static int indexOf(final Throwable throwable, final Class> type, int fromIndex, final boolean subclass) {
+ if (throwable == null || type == null) {
+ return -1;
+ }
+ if (fromIndex < 0) {
+ fromIndex = 0;
+ }
+ final Throwable[] throwables = ExceptionUtils.getThrowables(throwable);
+ if (fromIndex >= throwables.length) {
+ return -1;
+ }
+ if (subclass) {
+ for (int i = fromIndex; i < throwables.length; i++) {
+ if (type.isAssignableFrom(throwables[i].getClass())) {
+ return i;
+ }
+ }
+ } else {
+ for (int i = fromIndex; i < throwables.length; i++) {
+ if (type.equals(throwables[i].getClass())) {
+ return i;
+ }
+ }
+ }
+ return -1;
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * System.err
.printStackTrace
for throwables
+ * that don't have nested causes.printStackTrace
for throwables
+ * that don't have nested causes.null
+ * @since 2.0
+ */
+ public static void printRootCauseStackTrace(final Throwable throwable, final PrintStream stream) {
+ if (throwable == null) {
+ return;
+ }
+ if (stream == null) {
+ throw new IllegalArgumentException("The PrintStream must not be null");
+ }
+ final String trace[] = getRootCauseStackTrace(throwable);
+ for (final String element : trace) {
+ stream.println(element);
+ }
+ stream.flush();
+ }
+
+ /**
+ * printStackTrace
for throwables
+ * that don't have nested causes.null
+ * @since 2.0
+ */
+ public static void printRootCauseStackTrace(final Throwable throwable, final PrintWriter writer) {
+ if (throwable == null) {
+ return;
+ }
+ if (writer == null) {
+ throw new IllegalArgumentException("The PrintWriter must not be null");
+ }
+ final String trace[] = getRootCauseStackTrace(throwable);
+ for (final String element : trace) {
+ writer.println(element);
+ }
+ writer.flush();
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Throwable
.Throwable
to be examined
+ * @return the stack trace as generated by the exception's
+ * printStackTrace(PrintWriter)
method
+ */
+ public static String getStackTrace(final Throwable throwable) {
+ final StringWriter sw = new StringWriter();
+ final PrintWriter pw = new PrintWriter(sw, true);
+ throwable.printStackTrace(pw);
+ return sw.getBuffer().toString();
+ }
+
+ /**
+ * Throwable
object, decomposing it into a list of
+ * stack frames.Throwable
to examine, may be null
+ * @return an array of strings describing each stack frame, never null
+ */
+ public static String[] getStackFrames(final Throwable throwable) {
+ if (throwable == null) {
+ return ArrayUtils.EMPTY_STRING_ARRAY;
+ }
+ return getStackFrames(getStackTrace(throwable));
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * List
of stack frames - the message
+ * is not included. Only the trace of the specified exception is
+ * returned, any caused by trace is stripped." at".
+ * public int propagateExample { // note that there is no throws clause
+ * try {
+ * return invocation(); // throws IOException
+ * } catch (Exception e) {
+ * return ExceptionUtils.rethrow(e); // propagates a checked exception
+ * }
+ * }
+ *
+ *
+ * public int wrapExample { // note that there is no throws clause
+ * try {
+ * return invocation(); // throws IOException
+ * } catch (Error e) {
+ * throw e;
+ * } catch (RuntimeException e) {
+ * throw e; // wraps a checked exception
+ * } catch (Exception e) {
+ * throw new UndeclaredThrowableException(e); // wraps a checked exception
+ * }
+ * }
+ *
+ * Throwable
objects.ExceptionUtils
to be created, although that is not
+ * normally necessary.
+ * Throwable
to obtain the cause.Throwable
object. This will pick up most wrapping exceptions,
+ * including those from JDK 1.4.
+ *
+ *
+ *
+ *
+ * getCause()
getNextException()
getTargetException()
getException()
getSourceException()
getRootCause()
getCausedByException()
getNested()
null
.Throwable
,
+ * null
if none found or null throwable input
+ * @since 1.0
+ * @deprecated This feature will be removed in Lang 4.0, use {@link Throwable#getCause} instead
+ */
+ @Deprecated
+ public static Throwable getCause(final Throwable throwable) {
+ return getCause(throwable, null);
+ }
+
+ /**
+ * Throwable
to obtain the cause.null
set of method names means use the default set.
+ * A null
in the set of method names will be ignored.Throwable
,
+ * null
if none found or null throwable input
+ * @since 1.0
+ * @deprecated This feature will be removed in Lang 4.0, use {@link Throwable#getCause} instead
+ */
+ @Deprecated
+/**
+ * Throwable
to obtain the cause.null
set of method names means use the default set.
+ * A null
in the set of method names will be ignored.Throwable
,
+null
if none found or null throwable input
+ * @since 1.0
+ * @deprecated This feature will be removed in Lang 4.0, use {@link Throwable#getCause} instead
+ */
+public static java.lang.Throwable getCause(final java.lang.Throwable throwable, java.lang.String[] methodNames) {
+ if (throwable == null) {
+ return null;
+ }
+ if (methodNames == null) {
+ final java.lang.Throwable cause = throwable.getCause();
+ if (cause != null) {
+ return cause;
+ }
+ methodNames = org.apache.commons.lang3.exception.ExceptionUtils.CAUSE_METHOD_NAMES;
+ }
+ for (final java.lang.String methodName : methodNames) {
+ {
+ final java.lang.Throwable legacyCause = org.apache.commons.lang3.exception.ExceptionUtils.getCauseUsingMethodName(throwable, methodName);
+ {
+ return /* NPEX_NULL_EXP */
+ legacyCause;
+ }
+ }
+ }
+ return null;
+}
+
+ /**
+ * Throwable
to obtain the root cause.Throwable
,
+ * null
if none found or null throwable input
+ */
+ public static Throwable getRootCause(final Throwable throwable) {
+ final ListThrowable
by method name.null
if not found
+ */
+ // TODO: Remove in Lang 4.0
+ private static Throwable getCauseUsingMethodName(final Throwable throwable, final String methodName) {
+ Method method = null;
+ try {
+ method = throwable.getClass().getMethod(methodName);
+ } catch (final NoSuchMethodException ignored) { // NOPMD
+ // exception ignored
+ } catch (final SecurityException ignored) { // NOPMD
+ // exception ignored
+ }
+
+ if (method != null && Throwable.class.isAssignableFrom(method.getReturnType())) {
+ try {
+ return (Throwable) method.invoke(throwable);
+ } catch (final IllegalAccessException ignored) { // NOPMD
+ // exception ignored
+ } catch (final IllegalArgumentException ignored) { // NOPMD
+ // exception ignored
+ } catch (final InvocationTargetException ignored) { // NOPMD
+ // exception ignored
+ }
+ }
+ return null;
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Throwable
objects in the
+ * exception chain.1
.
+ * A throwable with one cause will return 2
and so on.
+ * A null
throwable will return 0
.Throwable
objects in the
+ * exception chain.null
throwable will return an array of size zero.Throwable
objects in the
+ * exception chain.null
throwable will return a list of size zero.Throwable
+ * that matches the specified class (exactly) in the exception chain.
+ * Subclasses of the specified class do not match - see
+ * {@link #indexOfType(Throwable, Class)} for the opposite.null
throwable returns -1
.
+ * A null
type returns -1
.
+ * No match in the chain returns -1
.Throwable
+ * that matches the specified type in the exception chain from
+ * a specified index.
+ * Subclasses of the specified class do not match - see
+ * {@link #indexOfType(Throwable, Class, int)} for the opposite.null
throwable returns -1
.
+ * A null
type returns -1
.
+ * No match in the chain returns -1
.
+ * A negative start index is treated as zero.
+ * A start index greater than the number of throwables returns -1
.Throwable
+ * that matches the specified class or subclass in the exception chain.
+ * Subclasses of the specified class do match - see
+ * {@link #indexOfThrowable(Throwable, Class)} for the opposite.null
throwable returns -1
.
+ * A null
type returns -1
.
+ * No match in the chain returns -1
.Throwable
+ * that matches the specified type in the exception chain from
+ * a specified index.
+ * Subclasses of the specified class do match - see
+ * {@link #indexOfThrowable(Throwable, Class)} for the opposite.null
throwable returns -1
.
+ * A null
type returns -1
.
+ * No match in the chain returns -1
.
+ * A negative start index is treated as zero.
+ * A start index greater than the number of throwables returns -1
.indexOfType
methods.true
, compares with {@link Class#isAssignableFrom(Class)}, otherwise compares
+ * using references
+ * @return index of the type
within throwables nested within the specified throwable
+ */
+ private static int indexOf(final Throwable throwable, final Class> type, int fromIndex, final boolean subclass) {
+ if (throwable == null || type == null) {
+ return -1;
+ }
+ if (fromIndex < 0) {
+ fromIndex = 0;
+ }
+ final Throwable[] throwables = ExceptionUtils.getThrowables(throwable);
+ if (fromIndex >= throwables.length) {
+ return -1;
+ }
+ if (subclass) {
+ for (int i = fromIndex; i < throwables.length; i++) {
+ if (type.isAssignableFrom(throwables[i].getClass())) {
+ return i;
+ }
+ }
+ } else {
+ for (int i = fromIndex; i < throwables.length; i++) {
+ if (type.equals(throwables[i].getClass())) {
+ return i;
+ }
+ }
+ }
+ return -1;
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * System.err
.printStackTrace
for throwables
+ * that don't have nested causes.printStackTrace
for throwables
+ * that don't have nested causes.null
+ * @since 2.0
+ */
+ public static void printRootCauseStackTrace(final Throwable throwable, final PrintStream stream) {
+ if (throwable == null) {
+ return;
+ }
+ if (stream == null) {
+ throw new IllegalArgumentException("The PrintStream must not be null");
+ }
+ final String trace[] = getRootCauseStackTrace(throwable);
+ for (final String element : trace) {
+ stream.println(element);
+ }
+ stream.flush();
+ }
+
+ /**
+ * printStackTrace
for throwables
+ * that don't have nested causes.null
+ * @since 2.0
+ */
+ public static void printRootCauseStackTrace(final Throwable throwable, final PrintWriter writer) {
+ if (throwable == null) {
+ return;
+ }
+ if (writer == null) {
+ throw new IllegalArgumentException("The PrintWriter must not be null");
+ }
+ final String trace[] = getRootCauseStackTrace(throwable);
+ for (final String element : trace) {
+ writer.println(element);
+ }
+ writer.flush();
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Throwable
.Throwable
to be examined
+ * @return the stack trace as generated by the exception's
+ * printStackTrace(PrintWriter)
method
+ */
+ public static String getStackTrace(final Throwable throwable) {
+ final StringWriter sw = new StringWriter();
+ final PrintWriter pw = new PrintWriter(sw, true);
+ throwable.printStackTrace(pw);
+ return sw.getBuffer().toString();
+ }
+
+ /**
+ * Throwable
object, decomposing it into a list of
+ * stack frames.Throwable
to examine, may be null
+ * @return an array of strings describing each stack frame, never null
+ */
+ public static String[] getStackFrames(final Throwable throwable) {
+ if (throwable == null) {
+ return ArrayUtils.EMPTY_STRING_ARRAY;
+ }
+ return getStackFrames(getStackTrace(throwable));
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * List
of stack frames - the message
+ * is not included. Only the trace of the specified exception is
+ * returned, any caused by trace is stripped." at".
+ * public int propagateExample { // note that there is no throws clause
+ * try {
+ * return invocation(); // throws IOException
+ * } catch (Exception e) {
+ * return ExceptionUtils.rethrow(e); // propagates a checked exception
+ * }
+ * }
+ *
+ *
+ * public int wrapExample { // note that there is no throws clause
+ * try {
+ * return invocation(); // throws IOException
+ * } catch (Error e) {
+ * throw e;
+ * } catch (RuntimeException e) {
+ * throw e; // wraps a checked exception
+ * } catch (Exception e) {
+ * throw new UndeclaredThrowableException(e); // wraps a checked exception
+ * }
+ * }
+ *
+ * Throwable
objects.ExceptionUtils
to be created, although that is not
+ * normally necessary.
+ * Throwable
to obtain the cause.Throwable
object. This will pick up most wrapping exceptions,
+ * including those from JDK 1.4.
+ *
+ *
+ *
+ *
+ * getCause()
getNextException()
getTargetException()
getException()
getSourceException()
getRootCause()
getCausedByException()
getNested()
null
.Throwable
,
+ * null
if none found or null throwable input
+ * @since 1.0
+ * @deprecated This feature will be removed in Lang 4.0, use {@link Throwable#getCause} instead
+ */
+ @Deprecated
+ public static Throwable getCause(final Throwable throwable) {
+ return getCause(throwable, null);
+ }
+
+ /**
+ * Throwable
to obtain the cause.null
set of method names means use the default set.
+ * A null
in the set of method names will be ignored.Throwable
,
+ * null
if none found or null throwable input
+ * @since 1.0
+ * @deprecated This feature will be removed in Lang 4.0, use {@link Throwable#getCause} instead
+ */
+ @Deprecated
+ public static Throwable getCause(final Throwable throwable, String[] methodNames) {
+ if (throwable == null) {
+ return null;
+ }
+
+ if (methodNames == null) {
+ final Throwable cause = throwable.getCause();
+ if (cause != null) {
+ return cause;
+ }
+
+ methodNames = CAUSE_METHOD_NAMES;
+ }
+
+ for (final String methodName : methodNames) {
+ if (methodName != null) {
+ final Throwable legacyCause = getCauseUsingMethodName(throwable, methodName);
+ if (legacyCause != null) {
+ return legacyCause;
+ }
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Throwable
to obtain the root cause.Throwable
,
+ * null
if none found or null throwable input
+ */
+ public static Throwable getRootCause(final Throwable throwable) {
+ final ListThrowable
by method name.null
if not found
+ */
+ // TODO: Remove in Lang 4.0
+ private static Throwable getCauseUsingMethodName(final Throwable throwable, final String methodName) {
+ Method method = null;
+ try {
+ method = throwable.getClass().getMethod(methodName);
+ } catch (final NoSuchMethodException ignored) { // NOPMD
+ // exception ignored
+ } catch (final SecurityException ignored) { // NOPMD
+ // exception ignored
+ }
+
+ if (method != null && Throwable.class.isAssignableFrom(method.getReturnType())) {
+ try {
+ return (Throwable) method.invoke(throwable);
+ } catch (final IllegalAccessException ignored) { // NOPMD
+ // exception ignored
+ } catch (final IllegalArgumentException ignored) { // NOPMD
+ // exception ignored
+ } catch (final InvocationTargetException ignored) { // NOPMD
+ // exception ignored
+ }
+ }
+ return null;
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Throwable
objects in the
+ * exception chain.1
.
+ * A throwable with one cause will return 2
and so on.
+ * A null
throwable will return 0
.Throwable
objects in the
+ * exception chain.null
throwable will return an array of size zero.Throwable
objects in the
+ * exception chain.null
throwable will return a list of size zero.Throwable
+ * that matches the specified class (exactly) in the exception chain.
+ * Subclasses of the specified class do not match - see
+ * {@link #indexOfType(Throwable, Class)} for the opposite.null
throwable returns -1
.
+ * A null
type returns -1
.
+ * No match in the chain returns -1
.Throwable
+ * that matches the specified type in the exception chain from
+ * a specified index.
+ * Subclasses of the specified class do not match - see
+ * {@link #indexOfType(Throwable, Class, int)} for the opposite.null
throwable returns -1
.
+ * A null
type returns -1
.
+ * No match in the chain returns -1
.
+ * A negative start index is treated as zero.
+ * A start index greater than the number of throwables returns -1
.Throwable
+ * that matches the specified class or subclass in the exception chain.
+ * Subclasses of the specified class do match - see
+ * {@link #indexOfThrowable(Throwable, Class)} for the opposite.null
throwable returns -1
.
+ * A null
type returns -1
.
+ * No match in the chain returns -1
.Throwable
+ * that matches the specified type in the exception chain from
+ * a specified index.
+ * Subclasses of the specified class do match - see
+ * {@link #indexOfThrowable(Throwable, Class)} for the opposite.null
throwable returns -1
.
+ * A null
type returns -1
.
+ * No match in the chain returns -1
.
+ * A negative start index is treated as zero.
+ * A start index greater than the number of throwables returns -1
.indexOfType
methods.true
, compares with {@link Class#isAssignableFrom(Class)}, otherwise compares
+ * using references
+ * @return index of the type
within throwables nested within the specified throwable
+ */
+ private static int indexOf(final Throwable throwable, final Class> type, int fromIndex, final boolean subclass) {
+ if (throwable == null || type == null) {
+ return -1;
+ }
+ if (fromIndex < 0) {
+ fromIndex = 0;
+ }
+ final Throwable[] throwables = ExceptionUtils.getThrowables(throwable);
+ if (fromIndex >= throwables.length) {
+ return -1;
+ }
+ if (subclass) {
+ for (int i = fromIndex; i < throwables.length; i++) {
+ if (type.isAssignableFrom(throwables[i].getClass())) {
+ return i;
+ }
+ }
+ } else {
+ for (int i = fromIndex; i < throwables.length; i++) {
+ if (type.equals(throwables[i].getClass())) {
+ return i;
+ }
+ }
+ }
+ return -1;
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * System.err
.printStackTrace
for throwables
+ * that don't have nested causes.printStackTrace
for throwables
+ * that don't have nested causes.null
+ * @since 2.0
+ */
+/**
+ * printStackTrace
for throwables
+ * that don't have nested causes.null
+ * @since 2.0
+ */
+public static void printRootCauseStackTrace(final java.lang.Throwable throwable, final java.io.PrintStream stream) {
+ {
+ if (stream == null) {
+ throw new java.lang.IllegalArgumentException("The PrintStream must not be null");
+ }
+ final java.lang.String[] trace = org.apache.commons.lang3.exception.ExceptionUtils.getRootCauseStackTrace(/* NPEX_NULL_EXP */
+ throwable);
+ for (final java.lang.String element : trace) {
+ stream.println(element);
+ }
+ stream.flush();
+ }
+}
+
+ /**
+ * printStackTrace
for throwables
+ * that don't have nested causes.null
+ * @since 2.0
+ */
+ public static void printRootCauseStackTrace(final Throwable throwable, final PrintWriter writer) {
+ if (throwable == null) {
+ return;
+ }
+ if (writer == null) {
+ throw new IllegalArgumentException("The PrintWriter must not be null");
+ }
+ final String trace[] = getRootCauseStackTrace(throwable);
+ for (final String element : trace) {
+ writer.println(element);
+ }
+ writer.flush();
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Throwable
.Throwable
to be examined
+ * @return the stack trace as generated by the exception's
+ * printStackTrace(PrintWriter)
method
+ */
+ public static String getStackTrace(final Throwable throwable) {
+ final StringWriter sw = new StringWriter();
+ final PrintWriter pw = new PrintWriter(sw, true);
+ throwable.printStackTrace(pw);
+ return sw.getBuffer().toString();
+ }
+
+ /**
+ * Throwable
object, decomposing it into a list of
+ * stack frames.Throwable
to examine, may be null
+ * @return an array of strings describing each stack frame, never null
+ */
+ public static String[] getStackFrames(final Throwable throwable) {
+ if (throwable == null) {
+ return ArrayUtils.EMPTY_STRING_ARRAY;
+ }
+ return getStackFrames(getStackTrace(throwable));
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * List
of stack frames - the message
+ * is not included. Only the trace of the specified exception is
+ * returned, any caused by trace is stripped." at".
+ * public int propagateExample { // note that there is no throws clause
+ * try {
+ * return invocation(); // throws IOException
+ * } catch (Exception e) {
+ * return ExceptionUtils.rethrow(e); // propagates a checked exception
+ * }
+ * }
+ *
+ *
+ * public int wrapExample { // note that there is no throws clause
+ * try {
+ * return invocation(); // throws IOException
+ * } catch (Error e) {
+ * throw e;
+ * } catch (RuntimeException e) {
+ * throw e; // wraps a checked exception
+ * } catch (Exception e) {
+ * throw new UndeclaredThrowableException(e); // wraps a checked exception
+ * }
+ * }
+ *
+ * Throwable
objects.ExceptionUtils
to be created, although that is not
+ * normally necessary.
+ * Throwable
to obtain the cause.Throwable
object. This will pick up most wrapping exceptions,
+ * including those from JDK 1.4.
+ *
+ *
+ *
+ *
+ * getCause()
getNextException()
getTargetException()
getException()
getSourceException()
getRootCause()
getCausedByException()
getNested()
null
.Throwable
,
+ * null
if none found or null throwable input
+ * @since 1.0
+ * @deprecated This feature will be removed in Lang 4.0, use {@link Throwable#getCause} instead
+ */
+ @Deprecated
+ public static Throwable getCause(final Throwable throwable) {
+ return getCause(throwable, null);
+ }
+
+ /**
+ * Throwable
to obtain the cause.null
set of method names means use the default set.
+ * A null
in the set of method names will be ignored.Throwable
,
+ * null
if none found or null throwable input
+ * @since 1.0
+ * @deprecated This feature will be removed in Lang 4.0, use {@link Throwable#getCause} instead
+ */
+ @Deprecated
+ public static Throwable getCause(final Throwable throwable, String[] methodNames) {
+ if (throwable == null) {
+ return null;
+ }
+
+ if (methodNames == null) {
+ final Throwable cause = throwable.getCause();
+ if (cause != null) {
+ return cause;
+ }
+
+ methodNames = CAUSE_METHOD_NAMES;
+ }
+
+ for (final String methodName : methodNames) {
+ if (methodName != null) {
+ final Throwable legacyCause = getCauseUsingMethodName(throwable, methodName);
+ if (legacyCause != null) {
+ return legacyCause;
+ }
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Throwable
to obtain the root cause.Throwable
,
+ * null
if none found or null throwable input
+ */
+ public static Throwable getRootCause(final Throwable throwable) {
+ final ListThrowable
by method name.null
if not found
+ */
+ // TODO: Remove in Lang 4.0
+ private static Throwable getCauseUsingMethodName(final Throwable throwable, final String methodName) {
+ Method method = null;
+ try {
+ method = throwable.getClass().getMethod(methodName);
+ } catch (final NoSuchMethodException ignored) { // NOPMD
+ // exception ignored
+ } catch (final SecurityException ignored) { // NOPMD
+ // exception ignored
+ }
+
+ if (method != null && Throwable.class.isAssignableFrom(method.getReturnType())) {
+ try {
+ return (Throwable) method.invoke(throwable);
+ } catch (final IllegalAccessException ignored) { // NOPMD
+ // exception ignored
+ } catch (final IllegalArgumentException ignored) { // NOPMD
+ // exception ignored
+ } catch (final InvocationTargetException ignored) { // NOPMD
+ // exception ignored
+ }
+ }
+ return null;
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Throwable
objects in the
+ * exception chain.1
.
+ * A throwable with one cause will return 2
and so on.
+ * A null
throwable will return 0
.Throwable
objects in the
+ * exception chain.null
throwable will return an array of size zero.Throwable
objects in the
+ * exception chain.null
throwable will return a list of size zero.Throwable
+ * that matches the specified class (exactly) in the exception chain.
+ * Subclasses of the specified class do not match - see
+ * {@link #indexOfType(Throwable, Class)} for the opposite.null
throwable returns -1
.
+ * A null
type returns -1
.
+ * No match in the chain returns -1
.Throwable
+ * that matches the specified type in the exception chain from
+ * a specified index.
+ * Subclasses of the specified class do not match - see
+ * {@link #indexOfType(Throwable, Class, int)} for the opposite.null
throwable returns -1
.
+ * A null
type returns -1
.
+ * No match in the chain returns -1
.
+ * A negative start index is treated as zero.
+ * A start index greater than the number of throwables returns -1
.Throwable
+ * that matches the specified class or subclass in the exception chain.
+ * Subclasses of the specified class do match - see
+ * {@link #indexOfThrowable(Throwable, Class)} for the opposite.null
throwable returns -1
.
+ * A null
type returns -1
.
+ * No match in the chain returns -1
.Throwable
+ * that matches the specified type in the exception chain from
+ * a specified index.
+ * Subclasses of the specified class do match - see
+ * {@link #indexOfThrowable(Throwable, Class)} for the opposite.null
throwable returns -1
.
+ * A null
type returns -1
.
+ * No match in the chain returns -1
.
+ * A negative start index is treated as zero.
+ * A start index greater than the number of throwables returns -1
.indexOfType
methods.true
, compares with {@link Class#isAssignableFrom(Class)}, otherwise compares
+ * using references
+ * @return index of the type
within throwables nested within the specified throwable
+ */
+ private static int indexOf(final Throwable throwable, final Class> type, int fromIndex, final boolean subclass) {
+ if (throwable == null || type == null) {
+ return -1;
+ }
+ if (fromIndex < 0) {
+ fromIndex = 0;
+ }
+ final Throwable[] throwables = ExceptionUtils.getThrowables(throwable);
+ if (fromIndex >= throwables.length) {
+ return -1;
+ }
+ if (subclass) {
+ for (int i = fromIndex; i < throwables.length; i++) {
+ if (type.isAssignableFrom(throwables[i].getClass())) {
+ return i;
+ }
+ }
+ } else {
+ for (int i = fromIndex; i < throwables.length; i++) {
+ if (type.equals(throwables[i].getClass())) {
+ return i;
+ }
+ }
+ }
+ return -1;
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * System.err
.printStackTrace
for throwables
+ * that don't have nested causes.printStackTrace
for throwables
+ * that don't have nested causes.null
+ * @since 2.0
+ */
+/**
+ * printStackTrace
for throwables
+ * that don't have nested causes.null
+ * @since 2.0
+ */
+public static void printRootCauseStackTrace(final java.lang.Throwable throwable, final java.io.PrintStream stream) {
+ if (throwable == null) {
+ return;
+ }
+ {
+ final java.lang.String[] trace = org.apache.commons.lang3.exception.ExceptionUtils.getRootCauseStackTrace(throwable);
+ for (final java.lang.String element : trace) {
+ /* NPEX_NULL_EXP */
+ stream.println(element);
+ }
+ stream.flush();
+ }
+}
+
+ /**
+ * printStackTrace
for throwables
+ * that don't have nested causes.null
+ * @since 2.0
+ */
+ public static void printRootCauseStackTrace(final Throwable throwable, final PrintWriter writer) {
+ if (throwable == null) {
+ return;
+ }
+ if (writer == null) {
+ throw new IllegalArgumentException("The PrintWriter must not be null");
+ }
+ final String trace[] = getRootCauseStackTrace(throwable);
+ for (final String element : trace) {
+ writer.println(element);
+ }
+ writer.flush();
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Throwable
.Throwable
to be examined
+ * @return the stack trace as generated by the exception's
+ * printStackTrace(PrintWriter)
method
+ */
+ public static String getStackTrace(final Throwable throwable) {
+ final StringWriter sw = new StringWriter();
+ final PrintWriter pw = new PrintWriter(sw, true);
+ throwable.printStackTrace(pw);
+ return sw.getBuffer().toString();
+ }
+
+ /**
+ * Throwable
object, decomposing it into a list of
+ * stack frames.Throwable
to examine, may be null
+ * @return an array of strings describing each stack frame, never null
+ */
+ public static String[] getStackFrames(final Throwable throwable) {
+ if (throwable == null) {
+ return ArrayUtils.EMPTY_STRING_ARRAY;
+ }
+ return getStackFrames(getStackTrace(throwable));
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * List
of stack frames - the message
+ * is not included. Only the trace of the specified exception is
+ * returned, any caused by trace is stripped." at".
+ * public int propagateExample { // note that there is no throws clause
+ * try {
+ * return invocation(); // throws IOException
+ * } catch (Exception e) {
+ * return ExceptionUtils.rethrow(e); // propagates a checked exception
+ * }
+ * }
+ *
+ *
+ * public int wrapExample { // note that there is no throws clause
+ * try {
+ * return invocation(); // throws IOException
+ * } catch (Error e) {
+ * throw e;
+ * } catch (RuntimeException e) {
+ * throw e; // wraps a checked exception
+ * } catch (Exception e) {
+ * throw new UndeclaredThrowableException(e); // wraps a checked exception
+ * }
+ * }
+ *
+ * Throwable
objects.ExceptionUtils
to be created, although that is not
+ * normally necessary.
+ * Throwable
to obtain the cause.Throwable
object. This will pick up most wrapping exceptions,
+ * including those from JDK 1.4.
+ *
+ *
+ *
+ *
+ * getCause()
getNextException()
getTargetException()
getException()
getSourceException()
getRootCause()
getCausedByException()
getNested()
null
.Throwable
,
+ * null
if none found or null throwable input
+ * @since 1.0
+ * @deprecated This feature will be removed in Lang 4.0, use {@link Throwable#getCause} instead
+ */
+ @Deprecated
+ public static Throwable getCause(final Throwable throwable) {
+ return getCause(throwable, null);
+ }
+
+ /**
+ * Throwable
to obtain the cause.null
set of method names means use the default set.
+ * A null
in the set of method names will be ignored.Throwable
,
+ * null
if none found or null throwable input
+ * @since 1.0
+ * @deprecated This feature will be removed in Lang 4.0, use {@link Throwable#getCause} instead
+ */
+ @Deprecated
+ public static Throwable getCause(final Throwable throwable, String[] methodNames) {
+ if (throwable == null) {
+ return null;
+ }
+
+ if (methodNames == null) {
+ final Throwable cause = throwable.getCause();
+ if (cause != null) {
+ return cause;
+ }
+
+ methodNames = CAUSE_METHOD_NAMES;
+ }
+
+ for (final String methodName : methodNames) {
+ if (methodName != null) {
+ final Throwable legacyCause = getCauseUsingMethodName(throwable, methodName);
+ if (legacyCause != null) {
+ return legacyCause;
+ }
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Throwable
to obtain the root cause.Throwable
,
+ * null
if none found or null throwable input
+ */
+ public static Throwable getRootCause(final Throwable throwable) {
+ final ListThrowable
by method name.null
if not found
+ */
+ // TODO: Remove in Lang 4.0
+ private static Throwable getCauseUsingMethodName(final Throwable throwable, final String methodName) {
+ Method method = null;
+ try {
+ method = throwable.getClass().getMethod(methodName);
+ } catch (final NoSuchMethodException ignored) { // NOPMD
+ // exception ignored
+ } catch (final SecurityException ignored) { // NOPMD
+ // exception ignored
+ }
+
+ if (method != null && Throwable.class.isAssignableFrom(method.getReturnType())) {
+ try {
+ return (Throwable) method.invoke(throwable);
+ } catch (final IllegalAccessException ignored) { // NOPMD
+ // exception ignored
+ } catch (final IllegalArgumentException ignored) { // NOPMD
+ // exception ignored
+ } catch (final InvocationTargetException ignored) { // NOPMD
+ // exception ignored
+ }
+ }
+ return null;
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Throwable
objects in the
+ * exception chain.1
.
+ * A throwable with one cause will return 2
and so on.
+ * A null
throwable will return 0
.Throwable
objects in the
+ * exception chain.null
throwable will return an array of size zero.Throwable
objects in the
+ * exception chain.null
throwable will return a list of size zero.Throwable
+ * that matches the specified class (exactly) in the exception chain.
+ * Subclasses of the specified class do not match - see
+ * {@link #indexOfType(Throwable, Class)} for the opposite.null
throwable returns -1
.
+ * A null
type returns -1
.
+ * No match in the chain returns -1
.Throwable
+ * that matches the specified type in the exception chain from
+ * a specified index.
+ * Subclasses of the specified class do not match - see
+ * {@link #indexOfType(Throwable, Class, int)} for the opposite.null
throwable returns -1
.
+ * A null
type returns -1
.
+ * No match in the chain returns -1
.
+ * A negative start index is treated as zero.
+ * A start index greater than the number of throwables returns -1
.Throwable
+ * that matches the specified class or subclass in the exception chain.
+ * Subclasses of the specified class do match - see
+ * {@link #indexOfThrowable(Throwable, Class)} for the opposite.null
throwable returns -1
.
+ * A null
type returns -1
.
+ * No match in the chain returns -1
.Throwable
+ * that matches the specified type in the exception chain from
+ * a specified index.
+ * Subclasses of the specified class do match - see
+ * {@link #indexOfThrowable(Throwable, Class)} for the opposite.null
throwable returns -1
.
+ * A null
type returns -1
.
+ * No match in the chain returns -1
.
+ * A negative start index is treated as zero.
+ * A start index greater than the number of throwables returns -1
.indexOfType
methods.true
, compares with {@link Class#isAssignableFrom(Class)}, otherwise compares
+ * using references
+ * @return index of the type
within throwables nested within the specified throwable
+ */
+ private static int indexOf(final Throwable throwable, final Class> type, int fromIndex, final boolean subclass) {
+ if (throwable == null || type == null) {
+ return -1;
+ }
+ if (fromIndex < 0) {
+ fromIndex = 0;
+ }
+ final Throwable[] throwables = ExceptionUtils.getThrowables(throwable);
+ if (fromIndex >= throwables.length) {
+ return -1;
+ }
+ if (subclass) {
+ for (int i = fromIndex; i < throwables.length; i++) {
+ if (type.isAssignableFrom(throwables[i].getClass())) {
+ return i;
+ }
+ }
+ } else {
+ for (int i = fromIndex; i < throwables.length; i++) {
+ if (type.equals(throwables[i].getClass())) {
+ return i;
+ }
+ }
+ }
+ return -1;
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * System.err
.printStackTrace
for throwables
+ * that don't have nested causes.printStackTrace
for throwables
+ * that don't have nested causes.null
+ * @since 2.0
+ */
+ public static void printRootCauseStackTrace(final Throwable throwable, final PrintStream stream) {
+ if (throwable == null) {
+ return;
+ }
+ if (stream == null) {
+ throw new IllegalArgumentException("The PrintStream must not be null");
+ }
+ final String trace[] = getRootCauseStackTrace(throwable);
+ for (final String element : trace) {
+ stream.println(element);
+ }
+ stream.flush();
+ }
+
+ /**
+ * printStackTrace
for throwables
+ * that don't have nested causes.null
+ * @since 2.0
+ */
+/**
+ * printStackTrace
for throwables
+ * that don't have nested causes.null
+ * @since 2.0
+ */
+public static void printRootCauseStackTrace(final java.lang.Throwable throwable, final java.io.PrintWriter writer) {
+ {
+ if (writer == null) {
+ throw new java.lang.IllegalArgumentException("The PrintWriter must not be null");
+ }
+ final java.lang.String[] trace = org.apache.commons.lang3.exception.ExceptionUtils.getRootCauseStackTrace(/* NPEX_NULL_EXP */
+ throwable);
+ for (final java.lang.String element : trace) {
+ writer.println(element);
+ }
+ writer.flush();
+ }
+}
+
+ //-----------------------------------------------------------------------
+ /**
+ * Throwable
.Throwable
to be examined
+ * @return the stack trace as generated by the exception's
+ * printStackTrace(PrintWriter)
method
+ */
+ public static String getStackTrace(final Throwable throwable) {
+ final StringWriter sw = new StringWriter();
+ final PrintWriter pw = new PrintWriter(sw, true);
+ throwable.printStackTrace(pw);
+ return sw.getBuffer().toString();
+ }
+
+ /**
+ * Throwable
object, decomposing it into a list of
+ * stack frames.Throwable
to examine, may be null
+ * @return an array of strings describing each stack frame, never null
+ */
+ public static String[] getStackFrames(final Throwable throwable) {
+ if (throwable == null) {
+ return ArrayUtils.EMPTY_STRING_ARRAY;
+ }
+ return getStackFrames(getStackTrace(throwable));
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * List
of stack frames - the message
+ * is not included. Only the trace of the specified exception is
+ * returned, any caused by trace is stripped." at".