Java 8でのProcess#destroyとProcess#destroyForciblyの環境差異について

Java 8のJavaDocでProcess#destoryとProcess#destroyForciblyメソッドを調べてみるとすごい怪しい記述がされています。

https://docs.oracle.com/javase/jp/8/docs/api/java/lang/Process.html


destroy

サブプロセスを終了します。このProcessオブジェクトが表すサブプロセスが強制終了されるかどうかは、実装によって異なります。

destroyForcibly

サブプロセスを終了します。このProcessオブジェクトが表すサブプロセスは強制終了されます。
このメソッドのデフォルト実装では、destroy()を呼び出すため、プロセスが強制終了されない場合があります。このクラスの具象実装では、このメソッドを準拠した実装でオーバーライドすることを強くお薦めします。ProcessBuilder.start()およびRuntime.exec(java.lang.String)から返されたProcessオブジェクトに対してこのメソッドを呼び出すと、プロセスが強制終了されます。

注: サブプロセスがただちに終了しない場合があります。つまり、destroyForcibly()が呼び出された後ほんのしばらくの間、isAlive()がtrueを返すことがあります。このメソッドは、必要に応じてwaitFor()にチェーンされることがあります。


実装によって異なりますとか、デフォルト実装ではとか・・・・・・

ということで調べた。

調べたら以下の通りでした。

  • WindowsではdestroyでもdestroyForciblyでもSIGTERM(kill -15)が呼ばれ、必ず強制終了される。
  • LinuxUnix系OSではdestroyではSIGKILL(kill -9)が呼ばれ、destroyForciblyではSIGTERM(kill -15)が呼ばれる。

なお、WindoesでSIGKILLを呼び出したい場合は、自分でnative実装を作成してJNIで呼び出すか、Processのインスタンスからプライベートフィールドとして定義されてるhandleを取得し、別コマンドとしてkilltask /PID pidを呼び出すのが良さそうです。

しかし、JavaDocでうたってるデフォルト実装通りなのがWindowsのみってどういうことなの・・・・・・・





Windows参考資料
http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/tip/src/windows/classes/java/lang/ProcessImpl.java#l475
http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/687fd7c7986d/src/windows/native/java/lang/ProcessImpl_md.c#l435
http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/tip/src/windows/classes/java/lang/ProcessImpl.java#l309

WindowsでもSIGKILLを送れないのかというとそんなことはあるわけがなくて、JavaではなぜかTerminateProcess関数が呼び出されているだけです。ExitProcess 関数というのも用意されています。
https://msdn.microsoft.com/ja-jp/library/cc429376.aspx

LinuxUnix系OS参考資料
http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/687fd7c7986d/src/solaris/classes/java/lang/UNIXProcess.java.bsd#l293
http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/687fd7c7986d/src/solaris/classes/java/lang/UNIXProcess.java.linux#l295
http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/687fd7c7986d/src/solaris/classes/java/lang/UNIXProcess.java.solaris#l247
http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/687fd7c7986d/src/solaris/native/java/lang/UNIXProcess_md.c#l715