
org.junit.jupiter.engine.extension.PreInterruptThreadDumpPrinter Maven / Gradle / Ivy
Show all versions of junit-jupiter-engine Show documentation
/*
* Copyright 2015-2025 the original author or authors.
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License v2.0 which
* accompanies this distribution and is available at
*
* https://www.eclipse.org/legal/epl-v20.html
*/
package org.junit.jupiter.engine.extension;
import java.util.Map;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.junit.jupiter.api.extension.PreInterruptCallback;
import org.junit.jupiter.api.extension.PreInterruptContext;
import org.junit.jupiter.engine.Constants;
/**
* The default implementation for {@link PreInterruptCallback},
* which will print the stacks of all {@link Thread}s to {@code System.out}.
*
* Note: This is disabled by default, and must be enabled with
* {@link Constants#EXTENSIONS_TIMEOUT_THREAD_DUMP_ENABLED_PROPERTY_NAME}
*
* @since 5.12
*/
final class PreInterruptThreadDumpPrinter implements PreInterruptCallback {
private static final String NL = "\n";
@Override
public void beforeThreadInterrupt(PreInterruptContext preInterruptContext, ExtensionContext extensionContext) {
Map stackTraces = Thread.getAllStackTraces();
StringBuilder sb = new StringBuilder();
sb.append("Thread ");
appendThreadName(sb, preInterruptContext.getThreadToInterrupt());
sb.append(" will be interrupted.");
sb.append(NL);
for (Map.Entry entry : stackTraces.entrySet()) {
Thread thread = entry.getKey();
StackTraceElement[] stack = entry.getValue();
if (stack.length > 0) {
sb.append(NL);
appendThreadName(sb, thread);
for (StackTraceElement stackTraceElement : stack) {
sb.append(NL);
//Do the same prefix as java.lang.Throwable.printStackTrace(java.lang.Throwable.PrintStreamOrWriter)
sb.append("\tat ");
sb.append(stackTraceElement.toString());
}
sb.append(NL);
}
}
System.out.println(sb);
}
/**
* Appends the {@link Thread} name and ID in a similar fashion as {@code jstack}.
* @param sb the buffer
* @param th the thread to append
*/
private void appendThreadName(StringBuilder sb, Thread th) {
// Use same format as java.lang.management.ThreadInfo.toString
sb.append("\"");
sb.append(th.getName());
sb.append("\"");
if (th.isDaemon()) {
sb.append(" daemon");
}
sb.append(" prio=");
sb.append(th.getPriority());
sb.append(" Id=");
sb.append(th.getId());
sb.append(" ");
sb.append(th.getState());
}
}