jodd-core/src/main/java/jodd/exception/ExceptionUtil.java
public static Throwable getRootCause(final Throwable throwable) {
		Throwable cause = throwable.getCause();
		if (cause == null) {
			return throwable;
		}

		Throwable t = throwable;

		// defend against (malicious?) circularity
		for (int i = 0; i < 1000; i++) {
			cause = t.getCause();
			if (cause == null) {
				return t;
			}
			t = cause;
		}

		return throwable;
	}
public static Throwable getRootCause(final Throwable throwable) {
		Throwable cause = throwable.getCause();
		if (cause == null) {
			return throwable;
		}

		Throwable t = throwable;

		// defend against (malicious?) circularity
		for (int i = 0; i < 1000; i++) {
			cause = t.getCause();
			if (cause == null) {
				return t;
			}
			t = cause;
		}

		return throwable;
	}
Introspects the <code>Throwable</code> to obtain the root cause.
<p>
This method walks through the exception chain to the last element,
"root" of the tree, and returns that exception. If no root cause found
returns provided throwable.