Java应用被手动强制停止时的日志记录实现咨询
Got it, let's break down how to log manual forced stops (like Task Manager kills) for your NetBeans-built Java app. The tricky part here is that hard process kills bypass the JVM's normal shutdown hooks, so we need a mix of Java-side tricks and Windows-specific tools to cover most cases:
Java Code Approaches
1. Signal Handlers (Covers Graceful Forced Stops)
Standard shutdown hooks (Runtime.getRuntime().addShutdownHook()) only trigger on exits like System.exit() or closing the GUI window normally. But for scenarios like Task Manager's "End Task" (for console/GUI apps) or Ctrl+C, you can register signal handlers for Windows-specific signals.
Here’s a implementation using the widely adopted (but non-official) sun.misc.Signal API:
import sun.misc.Signal; import sun.misc.SignalHandler; import java.util.logging.FileHandler; import java.util.logging.Logger; import java.util.logging.SimpleFormatter; public class ForceStopLogger { private static final Logger logger = Logger.getLogger(ForceStopLogger.class.getName()); public static void main(String[] args) { setupLogger(); registerSignalHandlers(); // Your core app logic here while (true) { try { Thread.sleep(1000); } catch (InterruptedException e) { logger.info("App interrupted"); Thread.currentThread().interrupt(); } } } private static void setupLogger() { try { FileHandler fileHandler = new FileHandler("app_stop.log", true); fileHandler.setFormatter(new SimpleFormatter()); logger.addHandler(fileHandler); logger.setUseParentHandlers(false); } catch (Exception e) { e.printStackTrace(); } } private static void registerSignalHandlers() { // Handle SIGTERM (sent by Task Manager's "End Task" or tools like taskkill without /F) Signal.handle(new Signal("TERM"), signal -> { logger.severe("Hey, your application was stopped manually ..."); System.exit(1); }); // Handle SIGINT (Ctrl+C in console) Signal.handle(new Signal("INT"), signal -> { logger.severe("Hey, your application was stopped manually ..."); System.exit(1); }); // Note: This won't catch hard "End Process" kills (SIGKILL equivalent) — need external tools for that } }
Heads up: The
sun.misc.SignalAPI isn't part of the official Java spec, but it works reliably with Oracle/OpenJDK on Windows. It won’t save you from immediate process termination (like Task Manager's "End Process" ortaskkill /F), though.
2. JNA for Windows System Event Listening
To catch even more termination scenarios, use JNA (Java Native Access) to hook into Windows process termination events. This gives you a better shot at logging before the process is killed.
First, add JNA dependencies to your NetBeans project (via Maven or download jna-5.x.x.jar and jna-platform-5.x.x.jar):
import com.sun.jna.platform.win32.Kernel32; import com.sun.jna.platform.win32.WinNT; import com.sun.jna.platform.win32.WinBase; import java.util.logging.Logger; import java.util.logging.FileHandler; import java.util.logging.SimpleFormatter; public class WindowsForceStopLogger { private static final Logger logger = Logger.getLogger(WindowsForceStopLogger.class.getName()); private static volatile boolean running = true; public static void main(String[] args) { setupLogger(); startTerminationListener(); // Your app logic here while (running) { try { Thread.sleep(1000); } catch (InterruptedException e) { running = false; } } } private static void setupLogger() { try { FileHandler fileHandler = new FileHandler("app_stop.log", true); fileHandler.setFormatter(new SimpleFormatter()); logger.addHandler(fileHandler); logger.setUseParentHandlers(false); } catch (Exception e) { e.printStackTrace(); } } private static void startTerminationListener() { Thread listenerThread = new Thread(() -> { WinNT.HANDLE hProcess = Kernel32.INSTANCE.GetCurrentProcess(); WinNT.HANDLE terminationEvent = Kernel32.INSTANCE.CreateEvent(null, true, false, null); // Register to get notified when the process is terminated if (!Kernel32.INSTANCE.RegisterWaitForSingleObject(null, hProcess, (wait, context) -> { logger.severe("Hey, your application was stopped manually ..."); running = false; }, null, WinBase.INFINITE, WinBase.WAIT_OBJECT_0)) { logger.warning("Failed to register termination listener"); } Kernel32.INSTANCE.WaitForMultipleObjects(1, new WinNT.HANDLE[]{terminationEvent}, true, WinBase.INFINITE); }); listenerThread.setDaemon(true); listenerThread.start(); } }
Limitations: Even with JNA, if the process is killed instantly (e.g.,
taskkill /F), the log might not write—since the OS gives no time for the JVM to execute code. But it’s more reliable than signal handlers for most manual stops.
Windows External Tool Approaches
For cases where Java code can’t keep up, use external Windows tools to monitor your app and log unexpected stops.
1. Batch Script Monitor
Create a batch file (run_app.bat) that starts your app and logs abnormal exits:
@echo off set APP_JAR=your_app.jar set LOG_FILE=app_stop.log :: Launch the app and wait for it to exit java -jar %APP_JAR% set EXIT_CODE=%errorlevel% :: Log if exit code is non-zero (indicates forced stop or crash) if %EXIT_CODE% neq 0 ( echo %date% %time% - Hey, your application was stopped manually ... >> %LOG_FILE% )
Catch: This won’t work if the batch script itself is killed, but it’s a quick, low-effort solution for common cases.
2. PowerShell Continuous Monitor
For more robust tracking, use a PowerShell script that checks if your app is running and logs when it disappears:
$processName = "java" # Use your app's exe name if it's compiled to native $logFile = "app_stop.log" $wasRunning = $true while ($true) { $process = Get-Process -Name $processName -ErrorAction SilentlyContinue if ($null -eq $process -and $wasRunning) { Add-Content -Path $logFile -Value "$(Get-Date) - Hey, your application was stopped manually ..." $wasRunning = $false } elseif ($null -ne $process -and -not $wasRunning) { $wasRunning = $true } Start-Sleep -Seconds 1 }
Run this script before starting your app—it’ll log every time the process vanishes unexpectedly.
Final Tips
- For the hardest termination cases (like
taskkill /F), no Java code can guarantee logging—since the OS immediately kills the process. External monitoring tools are your only option here. - Test each method in your specific scenario: "manual forced stop" can mean different things (End Task vs End Process, console vs GUI app), so pick the approach that fits your use case.
内容的提问来源于stack exchange,提问作者Onlikes

