JDK-6871190 : Don't terminate JVM if it is running in a non-interactive session
  • Type: Bug
  • Component: hotspot
  • Sub-Component: runtime
  • Affected Version: 6u14
  • Priority: P3
  • Status: Closed
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2009-08-12
  • Updated: 2014-06-26
  • Resolved: 2013-01-23
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 7 JDK 8 Other
7u40Fixed 8Fixed hs24Fixed
As explained in http://java.sun.com/j2se/1.4.2/docs/tooldocs/windows/java.html, JVM on Windows starts shutdown upon CTRL_LOGOFF_EVENT, unless the -Xrs option is set. As this document also explains, this behavior is undesirable for a Windows service.

The problem here is that if a Windows service can launch JVMs possible indirectly (such as a Windows service launching cmd.exe to do a batch file, which in turn launches JVM), and therefore adding -Xrs to every JVM invocation is neither practical nor desirable --- those JVMs that are indirectly launched may have no clue that it's running as a service, hence we can't expect their launcher scripts to have -Xrs.

According to the current MSDN documentation <http://msdn.microsoft.com/en-us/library/ms683242(VS.85).aspx>,  CTRL_LOGOFF_EVENT is explained as follows:

    A signal that the system sends to all console processes when a user is logging off.
    This signal does not indicate which user is logging off, so no assumptions can be made.

    Note that this signal is received only by services. Interactive applications are terminated
    at logoff, so they are not present when the system sends this signal.

So I find it odd that JVM initiates a shutdown hook in this case --- only a Windows service gets this, but they shouldn't initiates a shutdown! We'd be all better off if JVM ignores CTRL_LOGOFF_EVENT whatsoever.

If such change is impossible due to the compatibility constraints, I request that JVM recognizes an environment variable to activate -Xrs. Environment variables are inherited through a process tree, so in the situation described above, I can set it once at the service process and every JVM spawned directly/indirectly will have a proper protection against CTRL_LOGOFF_EVENT.

The title of the bug is misleading, the correct way to solve this is to use the example I posted a few months ago that detects if we're running in a non-interactive session or not.

Using environment variable in JVM is a no go, as it is a platform dependent feature.

EVALUATION Found out how to see if we're running as a service or not (thanks to Erik Joelsson who did this to support graphics testing in Tendril back in the days). Did the following change in consoleHandler(): case CTRL_CLOSE_EVENT: case CTRL_LOGOFF_EVENT: case CTRL_SHUTDOWN_EVENT: USEROBJECTFLAGS flags; GetUserObjectInformation(GetProcessWindowStation(), UOI_FLAGS, &flags, sizeof(USEROBJECTFLAGS), NULL); // 6871190: Don't terminate the JVM if we're running in a non-interactive // session (as a service) and the event is a LOGOFF event if ((flags.dwFlags & WSF_VISIBLE) == 0 && event == CTRL_LOGOFF_EVENT) { return TRUE; break; } WSF_VISIBLE won't be set for non-interactive logins, verified the fix by running Java as a service on WinXP and making sure it didn't terminate when a user logged off.