question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Java ShutDownHook not run

See original GitHub issue

Even with “stoptimeout” set, the ShutDownHook is never run when the service is stopped. The ShutDownHook does run if the Java application throws an uncaught exception.

Log is

2018-07-01 19:33:23,134 INFO - Stopping DRS IDB DEV Test 2018-07-01 19:33:23,149 DEBUG - ProcessKill 8732 2018-07-01 19:33:23,250 INFO - Found child process: 7420 Name: conhost.exe 2018-07-01 19:33:23,290 INFO - Stopping process 7420 2018-07-01 19:33:23,309 INFO - Send SIGINT 7420 2018-07-01 19:33:23,314 WARN - SIGINT to 7420 failed - Killing as fallback 2018-07-01 19:33:23,324 INFO - Stopping process 8732 2018-07-01 19:33:23,334 INFO - Send SIGINT 8732 2018-07-01 19:33:23,339 WARN - SIGINT to 8732 failed - Killing as fallback 2018-07-01 19:33:23,344 INFO - Finished DRS IDB DEV Test 2018-07-01 19:33:23,354 DEBUG - Completed. Exit code is 0

Code is

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Comments:7 (4 by maintainers)

github_iconTop GitHub Comments

1reaction
ryanruppcommented, Aug 21, 2019

I spent some more time looking at this. Given interrupt works when running the Java application from the command line but it doesn’t when running as a Windows service, I feel like this must be isolated to some protections/differences of launching the application as a sub process of a Windows service. The weird thing though is:

  1. I couldn’t find much information online that report this being an issue, most just suggest the same approach taken here
  2. I did find an “Azure Pipelines Agent” that does this exact same thing basically for a clean shutdown, see here - https://github.com/microsoft/azure-pipelines-agent/pull/161/files . This makes me think this should work so I’m not sure what other variables I’m missing here. Maybe some combination of windows service + java makes it happen. For example someone here - https://github.com/kohsuke/winsw/issues/95#issuecomment-466060692 - mentioned that SIGINT works correctly for Nginx. I barely have a Windows environment setup so this was hard for me to test but it would be good to just create a dummy C or Go based executable (suppose any language really although maybe one with minimal runtime e.g. C) that just does a sleep and verify interrupt works correctly.
  3. I still don’t understand why <stopparentprocessfirst>true</stopparentprocessfirst> makes it so it looks like SIGINT works but then shutdown hooks still do not run. Here’s example output of this startup/shutdown when I have configured this:
2019-08-21 12:20:58,941 INFO  - Starting ServiceWrapper in the service mode
2019-08-21 12:20:58,988 INFO  - Starting java -Xrs -Xmx128m -jar "C:\Users\myuser\myapp.jar"
2019-08-21 12:20:59,020 INFO  - Started process 1872
2019-08-21 12:20:59,035 DEBUG - Forwarding logs of the process System.Diagnostics.Process (java) to winsw.SizeBasedRollingLogAppender
2019-08-21 12:21:23,160 INFO  - Stopping my-app
2019-08-21 12:21:23,160 DEBUG - ProcessKill 1872
2019-08-21 12:21:23,176 INFO  - Stopping process 1872
2019-08-21 12:21:23,176 INFO  - Send SIGINT 1872
2019-08-21 12:21:23,222 INFO  - SIGINT to 1872 successful
2019-08-21 12:21:23,395 INFO  - Finished my-app
2019-08-21 12:21:23,395 DEBUG - Completed. Exit code is 0

The process is infact killed just the shutdown hooks don’t run.

0reactions
ryanruppcommented, Aug 14, 2019

Possibly related a bit to https://github.com/kohsuke/winsw/issues/95

On Windows 8 (just VM I had available, could try other versions from free dev VM downloads Microsoft provides) - I tried setting:

<stopparentprocessfirst>true</stopparentprocessfirst>

While it does report the SIGINT didn’t fail in this case, the shutdown hooks don’t end up running still. Different variations I’ve tried so far:

  1. Enabling/disabling -Xrs passed to java launch
  2. Trying to use javaw (doesn’t use a console) instead of java

I grabbed the sendctrlc executable from winp here - https://github.com/kohsuke/winp/blob/master/native/sendctrlc/main.cpp#L17 - which is basically doing the same thing this code appears to be doing. My results here are:

  1. When launching via winsw and calling sendctrlc the process cannot be interrupted and it ends with error code 5 (ERROR_ACCESS_DENIED)
  2. When launching the Java app just from command line and using sendctrlc it interrupts correctly (and runs shutdown hooks)

The documentation states:

If the calling process is already attached to a console, the error code returned is ERROR_ACCESS_DENIED (5)

So, I tried with javaw but it failed the same way. Not sure what’s going on as I’m not really familiar with the quirks of these APIs. I did end up finding winp in the first place because I was looking at how IntelliJ handles this as I believe it works correctly (although I use OSX primarily so need to verify that!). IntelliJ does delegate its graceful install to the winp library though which then does the same thing essentially that the winsw C# code is doing.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Java Shutdown hook not run
First thing to keep in mind is that it is not guaranteed that shutdown hooks will always run. If the JVM crashes due...
Read more >
JVM shutdown hook not working when stopping Java program ...
If you let it terminate, the shutdown message will appear on the console. But if you click the "stop" button or Ctrl-F2 while...
Read more >
Java ShutDownHook not run · Issue #283 · winsw ...
Even with "stoptimeout" set, the ShutDownHook is never run when the service is stopped. The ShutDownHook does run if the Java application ...
Read more >
Adding Shutdown Hooks for JVM Applications
Java provides a twin remove method to remove a particular shutdown hook after registering it: Thread willNotRun = new Thread(() -> System.out.
Read more >
JVM Shutdown Hook in Java
Shutdown Hooks are a special construct that allows developers to plug in a piece of code to be executed when the JVM is...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found