|
Groovy example source code file (StackTraceUtils.java)
This example Groovy source code file (StackTraceUtils.java) is included in the DevDaily.com
"Java Source Code
Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.
The Groovy StackTraceUtils.java source code
/*
* Copyright 2004-2007 the original author or authors.
*
* Licensed 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.codehaus.groovy.runtime;
import groovy.lang.Closure;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.LogManager;
import java.util.logging.Logger;
import org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation;
/**
* Originally was grails.utils.GrailsUtils, removed some grails specific stuff.
* Utility methods removing internal lines from stack traces
*
* @author Graeme Rocher
* @version $Revision: 5544 $
* @since 1.5
*/
public class StackTraceUtils {
public static final String STACK_LOG_NAME = "StackTrace";
private static final Logger STACK_LOG;
// set log to consume traces by default, end user can override later
static {
outer:
do {
Enumeration existingLogs = LogManager.getLogManager().getLoggerNames();
while (existingLogs.hasMoreElements()) {
if (STACK_LOG_NAME.equals(existingLogs.nextElement())) {
STACK_LOG = Logger.getLogger(STACK_LOG_NAME);
break outer;
}
}
STACK_LOG = Logger.getLogger(STACK_LOG_NAME);
STACK_LOG.setUseParentHandlers(false);
} while (false);
}
private static final String[] GROOVY_PACKAGES =
System.getProperty("groovy.sanitized.stacktraces",
"groovy.," +
"org.codehaus.groovy.," +
"java.," +
"javax.," +
"sun.," +
"gjdk.groovy.,"
).split("(\\s|,)+");
private static List<Closure> tests = new ArrayList();
/**
* <p>Adds a groovy.lang.Closure to test whether the stack trace
* element should be added or not.</p>
* <p>The groovy.lang.Closure will be given the class name as parameter.
* the return value decides if the element will be added or not.
* <ul>
* <li>true - trace element will be added to the trace
* <li>false - trace element will not be added to the trace
* <li>null - continue with next test
* </ul>
* Groovy truth will be used to determine true and false, null is excluded from
* defaulting to false here. If all tests have been executed and all of them skipped, then
* the groovy standard filtering will take place.</p>
*
* @param test the testing groovy.lang.Closure
*/
public static void addClassTest(Closure test) {
tests.add(test);
}
/**
* <p>Remove all apparently groovy-internal trace entries from the exception instance
* <p>This modifies the original instance and returns it, it does not clone
*
* @param t the Throwable whose stack trace we want to sanitize
* @return The original Throwable but with a sanitized stack trace
*/
public static Throwable sanitize(Throwable t) {
// Note that this getBoolean access may well be synced...
if (!Boolean.getBoolean("groovy.full.stacktrace")) {
StackTraceElement[] trace = t.getStackTrace();
List<StackTraceElement> newTrace = new ArrayList();
for (StackTraceElement stackTraceElement : trace) {
if (isApplicationClass(stackTraceElement.getClassName())) {
newTrace.add(stackTraceElement);
}
}
// We don't want to lose anything, so log it
STACK_LOG.log(Level.WARNING, "Sanitizing stacktrace:", t);
StackTraceElement[] clean = new StackTraceElement[newTrace.size()];
newTrace.toArray(clean);
t.setStackTrace(clean);
}
return t;
}
public static void printSanitizedStackTrace(Throwable t, PrintWriter p) {
t = StackTraceUtils.sanitize(t);
StackTraceElement[] trace = t.getStackTrace();
for (StackTraceElement stackTraceElement : trace) {
p.println("at " + stackTraceElement.getClassName()
+ "(" + stackTraceElement.getMethodName()
+ ":" + stackTraceElement.getLineNumber() + ")");
}
}
public static void printSanitizedStackTrace(Throwable t) {
printSanitizedStackTrace(t, new PrintWriter(System.err));
}
public static boolean isApplicationClass(String className) {
for (Closure test : tests) {
Object result = test.call(className);
if (result != null) {
return DefaultTypeTransformation.castToBoolean(result);
}
}
for (String groovyPackage : GROOVY_PACKAGES) {
if (className.startsWith(groovyPackage)) {
return false;
}
}
return true;
}
/**
* <p>Extracts the root cause of the exception, no matter how nested it is
*
* @param t a Throwable
* @return The deepest cause of the exception that can be found
*/
public static Throwable extractRootCause(Throwable t) {
Throwable result = t;
while (result.getCause() != null) {
result = result.getCause();
}
return result;
}
/**
* <p>Get the root cause of an exception and sanitize it for display to the user
* <p>This will MODIFY the stacktrace of the root cause exception object and return it
*
* @param t a throwable
* @return The root cause exception instance, with its stace trace modified to filter out groovy runtime classes
*/
public static Throwable sanitizeRootCause(Throwable t) {
return StackTraceUtils.sanitize(StackTraceUtils.extractRootCause(t));
}
/**
* <p>Sanitize the exception and ALL nested causes
* <p>This will MODIFY the stacktrace of the exception instance and all its causes irreversibly
*
* @param t a throwable
* @return The root cause exception instances, with stack trace modified to filter out groovy runtime classes
*/
public static Throwable deepSanitize(Throwable t) {
Throwable current = t;
while (current.getCause() != null) {
current = StackTraceUtils.sanitize(current.getCause());
}
return StackTraceUtils.sanitize(t);
}
}
Other Groovy examples (source code examples)
Here is a short list of links related to this Groovy StackTraceUtils.java source code file:
|