From 6890b94b16ddf758b38e03eb44be88a0e641c687 Mon Sep 17 00:00:00 2001 From: ME1312 Date: Sun, 1 Aug 2021 01:20:12 -0400 Subject: [PATCH] Implement Java 9 process termination Decided to finally use this now that people are updating their JDK versions. We can never have too many ways to track down and terminate processes around here, can we? --- .../SubServers/Bungee/Host/Executable.java | 29 +++++++++++++------ .../SubServers/Bungee/Library/Metrics.java | 1 - .../Host/Executable/Executable.java | 29 +++++++++++++------ 3 files changed, 40 insertions(+), 19 deletions(-) diff --git a/SubServers.Bungee/src/net/ME1312/SubServers/Bungee/Host/Executable.java b/SubServers.Bungee/src/net/ME1312/SubServers/Bungee/Host/Executable.java index 2c6e788f..cd459035 100644 --- a/SubServers.Bungee/src/net/ME1312/SubServers/Bungee/Host/Executable.java +++ b/SubServers.Bungee/src/net/ME1312/SubServers/Bungee/Host/Executable.java @@ -6,6 +6,7 @@ import net.ME1312.SubServers.Bungee.Library.Compatibility.JNA; import java.io.File; import java.io.IOException; +import java.util.stream.Stream; /** * Executable Handler Class @@ -93,18 +94,28 @@ public class Executable { */ public static void terminate(Process process) { if (process.isAlive()) { - Long pid = pid(process); - if (pid != null) try { - if (Platform.getSystem() == Platform.WINDOWS) { - Runtime.getRuntime().exec(new String[]{"taskkill.exe", "/T", "/F", "/PID", pid.toString()}).waitFor(); - } else if (USE_SESSION_TRACKING) { - Runtime.getRuntime().exec(new String[]{"bash", "-c", "kill -9 $(ps -s " + pid + " -o pid=)"}).waitFor(); - } - } catch (IOException | InterruptedException e) {} + Long pid; + if (Platform.getSystem() == Platform.WINDOWS) { + if ((pid = pid(process)) != null) Util.isException(() -> Runtime.getRuntime().exec(new String[]{"taskkill.exe", "/T", "/F", "/PID", pid.toString()}).waitFor()); + } else if (USE_SESSION_TRACKING) { + if ((pid = pid(process)) != null) Util.isException(() -> Runtime.getRuntime().exec(new String[]{"bash", "-c", "kill -9 $(ps -s " + pid + " -o pid=)"}).waitFor()); + } - if (process.isAlive()) { + if (process.isAlive() && terminate9(process)) { process.destroyForcibly(); } } } + + private static boolean terminate9(Object handle) { + try { // Attempt iteration over Java 9 ProcessHandle objects + Class clazz = handle.getClass(); + Stream children = (Stream) clazz.getMethod("descendants").invoke(handle); + clazz.getMethod("destroyForcibly").invoke(handle); + children.forEach(Executable::terminate9); + return false; + } catch (Throwable e) { + return true; + } + } } diff --git a/SubServers.Bungee/src/net/ME1312/SubServers/Bungee/Library/Metrics.java b/SubServers.Bungee/src/net/ME1312/SubServers/Bungee/Library/Metrics.java index 8122b675..f98fbed4 100644 --- a/SubServers.Bungee/src/net/ME1312/SubServers/Bungee/Library/Metrics.java +++ b/SubServers.Bungee/src/net/ME1312/SubServers/Bungee/Library/Metrics.java @@ -25,7 +25,6 @@ import java.util.function.BiConsumer; import java.util.function.Consumer; import java.util.function.Supplier; import java.util.logging.Level; -import java.util.regex.Pattern; import java.util.stream.Collectors; import java.util.zip.GZIPOutputStream; import javax.net.ssl.HttpsURLConnection; diff --git a/SubServers.Host/src/net/ME1312/SubServers/Host/Executable/Executable.java b/SubServers.Host/src/net/ME1312/SubServers/Host/Executable/Executable.java index b6c0f6f9..4bb5b31c 100644 --- a/SubServers.Host/src/net/ME1312/SubServers/Host/Executable/Executable.java +++ b/SubServers.Host/src/net/ME1312/SubServers/Host/Executable/Executable.java @@ -6,6 +6,7 @@ import net.ME1312.SubServers.Host.Library.Compatibility.JNA; import java.io.File; import java.io.IOException; +import java.util.stream.Stream; /** * Executable Handler Class @@ -93,18 +94,28 @@ public class Executable { */ public static void terminate(Process process) { if (process.isAlive()) { - Long pid = pid(process); - if (pid != null) try { - if (Platform.getSystem() == Platform.WINDOWS) { - Runtime.getRuntime().exec(new String[]{"taskkill.exe", "/T", "/F", "/PID", pid.toString()}).waitFor(); - } else if (USE_SESSION_TRACKING) { - Runtime.getRuntime().exec(new String[]{"bash", "-c", "kill -9 $(ps -s " + pid + " -o pid=)"}).waitFor(); - } - } catch (IOException | InterruptedException e) {} + Long pid; + if (Platform.getSystem() == Platform.WINDOWS) { + if ((pid = pid(process)) != null) Util.isException(() -> Runtime.getRuntime().exec(new String[]{"taskkill.exe", "/T", "/F", "/PID", pid.toString()}).waitFor()); + } else if (USE_SESSION_TRACKING) { + if ((pid = pid(process)) != null) Util.isException(() -> Runtime.getRuntime().exec(new String[]{"bash", "-c", "kill -9 $(ps -s " + pid + " -o pid=)"}).waitFor()); + } - if (process.isAlive()) { + if (process.isAlive() && terminate9(process)) { process.destroyForcibly(); } } } + + private static boolean terminate9(Object handle) { + try { // Attempt iteration over Java 9 ProcessHandle objects + Class clazz = handle.getClass(); + Stream children = (Stream) clazz.getMethod("descendants").invoke(handle); + clazz.getMethod("destroyForcibly").invoke(handle); + children.forEach(Executable::terminate9); + return false; + } catch (Throwable e) { + return true; + } + } }