You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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.Signal API 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" or taskkill /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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 10:13:53