/** static convenience for {@link #cleaned(Throwable)} */ public static <T extends Throwable> T cleanedStackTrace(T t) { return DEFAULT_INSTACE.cleaned(t); }
public static StackTraceSimplifier newInstance(String ...additionalBlacklistPackagePrefixes) { return new StackTraceSimplifier(true, additionalBlacklistPackagePrefixes); }
/** static convenience for {@link #clean(Iterable)} */ public static List<StackTraceElement> cleanStackTrace(Iterable<StackTraceElement> st) { return DEFAULT_INSTACE.clean(st); }
/** returns the number of times the calling method occurs elsewhere in the stack trace; * 0 if no recursion, 1 if it has cycled three times, etc. */ @Beta // useful to track down things like https://github.com/apache/incubator-brooklyn/pull/489 public static int getRecursiveCallCount() { StackTraceElement[] t = cleanStackTrace(new Throwable().getStackTrace()); Iterator<StackTraceElement> ti = Arrays.asList(t).iterator(); ti.next(); if (!ti.hasNext()) return 0; // t0 is the caller StackTraceElement t0 = ti.next(); String l0 = t0.getClassName()+"."+t0.getMethodName()+"("+t0.getFileName()+")"; int count = 0; while (ti.hasNext()) { StackTraceElement ta = ti.next(); String li = ta.getClassName()+"."+ta.getMethodName()+"("+ta.getFileName()+")"; // if we have something in a different method, then something back in the method // from which the recursive check came, then return true if (li.equals(l0)) count++; } return count; } }
/** @return (n+1)th {@link #isUseful(StackTraceElement)} stack trace elements (ie 0 is {@link #firstUseful(StackTraceElement[])}), or null */ public StackTraceElement nthUseful(int n, StackTraceElement[] st) { for (StackTraceElement element: st){ if (isUseful(element)) { if (n==0) return element; n--; } } return null; }
/** @return first {@link #isUseful(StackTraceElement)} stack trace elements, or null */ public StackTraceElement firstUseful(StackTraceElement[] st) { return nthUseful(0, st); }
@Test public void cleanTestTrace() { RuntimeException t = StackTraceSimplifier.newInstance(StackTraceSimplifierTest.class.getName()) .cleaned(new RuntimeException("sample")); // should exclude *this* class also Assert.assertTrue(t.getStackTrace()[0].getClassName().startsWith("org.testng"), "trace was: "+t.getStackTrace()[0]); }
public static int install(ResourceUtils resolver, Map<String, ?> props, SshMachineLocation machine, String urlToInstall, String target, int numAttempts) { if (resolver==null) resolver = ResourceUtils.create(machine); Exception lastError = null; int retriesRemaining = numAttempts; int attemptNum = 0; do { attemptNum++; try { Tasks.setBlockingDetails("Installing "+urlToInstall+" at "+machine); // TODO would be nice to have this in a task (and the things within it!) return machine.installTo(resolver, props, urlToInstall, target); } catch (Exception e) { Exceptions.propagateIfFatal(e); lastError = e; String stack = StackTraceSimplifier.toString(e); if (stack.contains("net.schmizz.sshj.sftp.RemoteFile.write")) { log.warn("Failed to transfer "+urlToInstall+" to "+machine+", retryable error, attempt "+attemptNum+"/"+numAttempts+": "+e); continue; } log.warn("Failed to transfer "+urlToInstall+" to "+machine+", not a retryable error so failing: "+e); throw Exceptions.propagate(e); } finally { Tasks.resetBlockingDetails(); } } while (retriesRemaining --> 0); throw Exceptions.propagate(lastError); }
@Test public void isStackTraceElementUsefulAcceptsANonBlacklistedPackage() { StackTraceElement el = new StackTraceElement( "brooklyn.util.task", "StackTraceSimplifierTest", "StackTraceSimplifierTest.groovy", 42); Assert.assertTrue(StackTraceSimplifier.isStackTraceElementUseful(el)); }
private int m1(int x) { int count = StackTraceSimplifier.getRecursiveCallCount(); if (count>100) throw new RuntimeException("expected"); if (x<=0) { return count; } return m2(x-1); } private int m2(int x) {
st = org.apache.brooklyn.util.javalang.StackTraceSimplifier.cleanStackTrace(st); if (st!=null && st.length>0) rv += "\n" +"At: "+st[0];
/** static convenience for {@link #isUseful(StackTraceElement)} */ public static boolean isStackTraceElementUseful(StackTraceElement el) { return DEFAULT_INSTACE.isUseful(el); }
/** returns top of cleaned stack trace; usually the caller's location */ public static StackTraceElement currentStackElement() { return STACK_TRACE_SIMPLIFIER_EXCLUDING_UTIL_JAVALANG.nthUseful(0, Thread.currentThread().getStackTrace()); }
@Test public void isStackTraceElementUsefulRejectsABlacklistedPackage() { StackTraceElement el = new StackTraceElement("groovy.lang.Foo", "bar", "groovy/lang/Foo.groovy", 42); Assert.assertFalse(StackTraceSimplifier.isStackTraceElementUseful(el)); }
/** static convenience for {@link #clean(StackTraceElement[])} */ public static StackTraceElement[] cleanStackTrace(StackTraceElement[] st) { return DEFAULT_INSTACE.clean(st); }
/** @return new list containing just the {@link #isUseful(StackTraceElement)} stack trace elements */ public List<StackTraceElement> clean(Iterable<StackTraceElement> st) { List<StackTraceElement> result = new LinkedList<StackTraceElement>(); for (StackTraceElement element: st){ if (isUseful(element)){ result.add(element); } } return result; }
/** returns element in cleaned stack trace; usually the caller's location is at the top, * and caller of that is up one, etc */ public static StackTraceElement callerStackElement(int depth) { return STACK_TRACE_SIMPLIFIER_EXCLUDING_UTIL_JAVALANG.nthUseful(depth, Thread.currentThread().getStackTrace()); }
public static StackTraceSimplifier newInstance() { return new StackTraceSimplifier(); }
/** returns a cleaned stack trace; caller is usually at the top */ public static StackTraceElement[] currentStackTraceCleaned() { return STACK_TRACE_SIMPLIFIER_EXCLUDING_UTIL_JAVALANG.clean( Thread.currentThread().getStackTrace()); }
public static StackTraceSimplifier newInstanceExcludingOnly(String ...blacklistPackagePrefixes) { return new StackTraceSimplifier(false, blacklistPackagePrefixes); }