JDK-8056139 : (process) Process::destroy should be graceful on Windows
  • Type: Enhancement
  • Component: core-libs
  • Sub-Component: java.lang
  • Affected Version: 8u11
  • Priority: P4
  • Status: Open
  • Resolution: Unresolved
  • OS: windows_8
  • CPU: x86
  • Submitted: 2014-08-09
  • Updated: 2014-12-11
Related Reports
Relates :  
Relates :  
Description
A DESCRIPTION OF THE REQUEST :
Current implementation on Windows JVM is to issue a TerminateProcess() on Process::destroy().

Now that Java8 has a Process::destroyForcibly(), which currently delegates to destroy(), the two methods should have separate implementations.

destroyForcibly() should call TerminateProcess()
destroy() should call ExitProcess()


JUSTIFICATION :
This will allow shutdown hooks to be called on Process::destroy(), just like on Solaris/Linux.




Comments
We can't change existing behavior so it would probably be a new method. The remote thread trick might not work for cases where the child is a different architecture (WOW64 for example) but may 32-bit is slowly going away so it may not be a big issue.
14-09-2014

The trick with installing a remote thread can be used to make the child call ExitProcess(). The following code was tested and worked well: diff --git a/src/java.base/windows/classes/java/lang/ProcessImpl.java b/src/java.base/windows/classes/java/lang/ProcessImpl.java --- a/src/java.base/windows/classes/java/lang/ProcessImpl.java +++ b/src/java.base/windows/classes/java/lang/ProcessImpl.java @@ -472,11 +472,16 @@ private static native void waitForTimeoutInterruptibly( long handle, long timeout); - public void destroy() { terminateProcess(handle); } + @Override + public void destroy() { + destroyProcessGracefully(handle); + } + + private static native void destroyProcessGracefully(long handle); @Override public Process destroyForcibly() { - destroy(); + terminateProcess(handle); return this; } diff --git a/src/java.base/windows/native/libjava/ProcessImpl_md.c b/src/java.base/windows/native/libjava/ProcessImpl_md.c --- a/src/java.base/windows/native/libjava/ProcessImpl_md.c +++ b/src/java.base/windows/native/libjava/ProcessImpl_md.c @@ -452,6 +452,29 @@ TerminateProcess((HANDLE) handle, 1); } +JNIEXPORT void JNICALL +Java_java_lang_ProcessImpl_destroyProcessGracefully(JNIEnv *env, jclass ignored, jlong handle) +{ + LPTHREAD_START_ROUTINE procExitProcess + = (LPTHREAD_START_ROUTINE)&ExitProcess; + + HANDLE hExitProcessThread + = CreateRemoteThread((HANDLE)handle, // process to terminate + NULL, // default security attributes + 65536, // default stack size, minimal 64 K + procExitProcess, // thread function + (LPVOID)1, // exit code + 0, // run immidiately (make it STACK_SIZE_PARAM_IS_A_RESERVATION?) + NULL); // no id + + if (hExitProcessThread != NULL) { + SetThreadPriority(hExitProcessThread, THREAD_PRIORITY_HIGHEST); + return; + } + TerminateProcess((HANDLE) handle, 1); +} + JNIEXPORT jboolean JNICALL Java_java_lang_ProcessImpl_isProcessAlive(JNIEnv *env, jclass ignored, jlong handle) { However, if this change is proposed, it will also require some adjustments to the spec.
14-09-2014

This has been discussed many times but I don't think we've found a good solution for Windows (the submitter suggests ExitProcess but that is for exiting the current process, not the child).
27-08-2014