Domanda

I am trying to get a shutdown hook to run in java. The purpose of this hook is to write into a log file that the program was terminated. The java application is compiled into a jar file and executed using a batch file, which means that the output of the application goes to a cmd.exe window. When this cmd window is closed, i want the application to log that it was closed.

The application is intended to run indefinitely and do certain tasks at a certain time. Therefore, the program is executing a series of checks within a "While true" loop. I do not understand why this hook will not log that the application is closing!

In the main method we have:

final Thread mainThread = Thread.currentThread();
Runtime.getRuntime().addShutdownHook(new Thread(new Runnable()
{
    @Override
    public void run()
    {
        try { mainThread.join(); }
        catch (InterruptedException e) { }
        mission.log("Program Closed.", true);
    }
}
));

All "mission" is, is an instance of a custom class of mine that does data logging. When you call the method "log", it has a BufferedWriter and it calls its .write(), .newLine(), and .flush() methods.

I can't seem to get the "Program Closed" line in my logfile when i kill the batch window. What am I doing wrong?

È stato utile?

Soluzione

Forcibly killing the application, i.e. not gracefully, so the JVM doesn't know that the application is exiting, therefore the shutdown hooks are not invoked.

Unfortunately, there is no way (in Windows, at least) to provide a mechanism that ensures that the hook is always invoked. It's just something that may be invoked, but there is no guarantee.

Altri suggerimenti

Closing the window kills the process so a shutdown hook won't work.

It sounds like you would rather not have this process killed at all. You should consider using something other than a batch script. You can run an executable jar from the windows task scheduler and have it running in the background all the time - unless someone intentionally kills java or an error occurs. In which case you should be trying to catch exceptions and log them that way.

There is no way to always execute something before your process exits. E.g. if you pull the plug out of the wall outlet, your computer shuts down immediately. Or if the process is killed by the operating system by removing it from the scheduler for CPU time, it also has no chance.

However, if you remove the code

    try { mainThread.join(); }
    catch (InterruptedException e) { }

Then it will at least be executed for certain cases, e.g. a normal termination of the process. Checking for the main thread here doesn't make sense, because either the shutdown hook is executed as a result of the main thread having finished its work (it exited the main() method), or the main thread will continue to run until the JVM decides to terminate (in case of termination from outside).

Compare the accepted answer of How to gracefully handle the SIGKILL signal in Java, which contains another example of what you're trying to do.

Everyone here is correct - you can't log a forcible stop on your program. However, you might consider using another program to 'watch' your program and wait for it to exit. The 'watcher' program can then log the termination of the original program and then exit itself.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top