Clean up Executable class

This commit is contained in:
ME1312 2021-02-24 20:07:20 -05:00
parent 2beec3ae7a
commit 15a4f109a4
No known key found for this signature in database
GPG Key ID: FEFFE2F698E88FA8
3 changed files with 57 additions and 40 deletions

View File

@ -1,9 +1,11 @@
package net.ME1312.SubServers.Bungee.Host; package net.ME1312.SubServers.Bungee.Host;
import net.ME1312.Galaxi.Library.Platform;
import net.ME1312.Galaxi.Library.Util; import net.ME1312.Galaxi.Library.Util;
import net.ME1312.SubServers.Bungee.Library.Compatibility.JNA; import net.ME1312.SubServers.Bungee.Library.Compatibility.JNA;
import java.io.File; import java.io.File;
import java.io.IOException;
/** /**
* Executable Handler Class * Executable Handler Class
@ -41,30 +43,34 @@ public class Executable {
* @param process Process * @param process Process
* @return Process ID (null if unknown) * @return Process ID (null if unknown)
*/ */
@SuppressWarnings("JavaReflectionMemberAccess")
public static Long pid(Process process) { public static Long pid(Process process) {
if (process.isAlive()) { if (process.isAlive()) {
try { try { // Java 9 Standard
return (long) Process.class.getDeclaredMethod("pid").invoke(process); return (long) Process.class.getMethod("pid").invoke(process);
} catch (Throwable ex) { } catch (Throwable e) {
try { try { // Java 8 Not-so-standard
if (process.getClass().getName().equals("java.lang.Win32Process") || process.getClass().getName().equals("java.lang.ProcessImpl")) { Object response = Util.reflect(process.getClass().getDeclaredField("pid"), process);
if (response instanceof Number) {
return ((Number) response).longValue();
} else throw e;
} catch (Throwable e2) {
if (Platform.getSystem() == Platform.WINDOWS) try {
long handle = Util.reflect(process.getClass().getDeclaredField("handle"), process); long handle = Util.reflect(process.getClass().getDeclaredField("handle"), process);
ClassLoader jna = JNA.get(); ClassLoader jna = JNA.get();
Class<?> pc = jna.loadClass("com.sun.jna.Pointer"), Class<?> pc = jna.loadClass("com.sun.jna.Pointer"),
ntc = jna.loadClass("com.sun.jna.platform.win32.WinNT$HANDLE"), ntc = jna.loadClass("com.sun.jna.platform.win32.WinNT$HANDLE"),
k32c = jna.loadClass("com.sun.jna.platform.win32.Kernel32"); k32c = jna.loadClass("com.sun.jna.platform.win32.Kernel32");
Object k32 = k32c.getField("INSTANCE").get(null), Object k32 = k32c.getField("INSTANCE").get(null),
nt = ntc.getConstructor().newInstance(); nt = ntc.getConstructor().newInstance();
ntc.getMethod("setPointer", pc).invoke(nt, pc.getMethod("createConstant", long.class).invoke(null, handle)); ntc.getMethod("setPointer", pc).invoke(nt, pc.getMethod("createConstant", long.class).invoke(null, handle));
return ((Number) k32c.getMethod("GetProcessId", ntc).invoke(k32, nt)).longValue(); return ((Number) k32c.getMethod("GetProcessId", ntc).invoke(k32, nt)).longValue();
} else if (process.getClass().getName().equals("java.lang.UNIXProcess")) { } catch (Throwable e3) {
Object response = Util.reflect(process.getClass().getDeclaredField("pid"), process); // No way to find pid, I suppose.
if (response instanceof Number)
return ((Number) response).longValue();
} }
} catch (Throwable e) {} }
} }
} }
return null; return null;
@ -77,14 +83,16 @@ public class Executable {
*/ */
public static void terminate(Process process) { public static void terminate(Process process) {
if (process.isAlive()) { if (process.isAlive()) {
if (System.getProperty("os.name").toLowerCase().startsWith("windows")) { Long pid = pid(process);
Long pid = pid(process); if (pid != null) try {
if (pid != null) try { if (Platform.getSystem() == Platform.WINDOWS) {
Process terminator = Runtime.getRuntime().exec(new String[]{"taskkill.exe", "/T", "/F", "/PID", pid.toString()}); Runtime.getRuntime().exec(new String[]{"taskkill.exe", "/T", "/F", "/PID", pid.toString()}).waitFor();
terminator.waitFor(); }
} catch (Throwable e) {} } catch (IOException | InterruptedException e) {}
if (process.isAlive()) {
process.destroyForcibly();
} }
if (process.isAlive()) process.destroyForcibly();
} }
} }
} }

View File

@ -137,6 +137,7 @@ public class InternalSubServer extends SubServerImpl {
} }
private void run() { private void run() {
boolean locked = lock;
allowrestart = true; allowrestart = true;
started = false; started = false;
try { try {
@ -150,7 +151,7 @@ public class InternalSubServer extends SubServerImpl {
Logger.get("SubServers").info("Now starting " + getName()); Logger.get("SubServers").info("Now starting " + getName());
logger.process = process; logger.process = process;
logger.start(); logger.start();
lock = false; lock = locked = false;
command = new BufferedWriter(new OutputStreamWriter(process.getOutputStream())); command = new BufferedWriter(new OutputStreamWriter(process.getOutputStream()));
for (LoggedCommand command : history) if (process.isAlive()) { for (LoggedCommand command : history) if (process.isAlive()) {
this.command.write(command.getCommand()); this.command.write(command.getCommand());
@ -161,8 +162,8 @@ public class InternalSubServer extends SubServerImpl {
if (process.isAlive()) process.waitFor(); if (process.isAlive()) process.waitFor();
} catch (IOException | InterruptedException e) { } catch (IOException | InterruptedException e) {
e.printStackTrace(); e.printStackTrace();
if (locked) lock = false;
allowrestart = false; allowrestart = false;
lock = false;
} }
Logger.get("SubServers").info(getName() + " has stopped"); Logger.get("SubServers").info(getName() + " has stopped");

View File

@ -1,9 +1,11 @@
package net.ME1312.SubServers.Host.Executable; package net.ME1312.SubServers.Host.Executable;
import net.ME1312.Galaxi.Library.Platform;
import net.ME1312.Galaxi.Library.Util; import net.ME1312.Galaxi.Library.Util;
import net.ME1312.SubServers.Host.Library.Compatibility.JNA; import net.ME1312.SubServers.Host.Library.Compatibility.JNA;
import java.io.File; import java.io.File;
import java.io.IOException;
/** /**
* Executable Handler Class * Executable Handler Class
@ -41,30 +43,34 @@ public class Executable {
* @param process Process * @param process Process
* @return Process ID (null if unknown) * @return Process ID (null if unknown)
*/ */
@SuppressWarnings("JavaReflectionMemberAccess")
public static Long pid(Process process) { public static Long pid(Process process) {
if (process.isAlive()) { if (process.isAlive()) {
try { try { // Java 9 Standard
return (long) Process.class.getDeclaredMethod("pid").invoke(process); return (long) Process.class.getMethod("pid").invoke(process);
} catch (Throwable ex) { } catch (Throwable e) {
try { try { // Java 8 Not-so-standard
if (process.getClass().getName().equals("java.lang.Win32Process") || process.getClass().getName().equals("java.lang.ProcessImpl")) { Object response = Util.reflect(process.getClass().getDeclaredField("pid"), process);
if (response instanceof Number) {
return ((Number) response).longValue();
} else throw e;
} catch (Throwable e2) {
if (Platform.getSystem() == Platform.WINDOWS) try {
long handle = Util.reflect(process.getClass().getDeclaredField("handle"), process); long handle = Util.reflect(process.getClass().getDeclaredField("handle"), process);
ClassLoader jna = JNA.get(); ClassLoader jna = JNA.get();
Class<?> pc = jna.loadClass("com.sun.jna.Pointer"), Class<?> pc = jna.loadClass("com.sun.jna.Pointer"),
ntc = jna.loadClass("com.sun.jna.platform.win32.WinNT$HANDLE"), ntc = jna.loadClass("com.sun.jna.platform.win32.WinNT$HANDLE"),
k32c = jna.loadClass("com.sun.jna.platform.win32.Kernel32"); k32c = jna.loadClass("com.sun.jna.platform.win32.Kernel32");
Object k32 = k32c.getField("INSTANCE").get(null), Object k32 = k32c.getField("INSTANCE").get(null),
nt = ntc.getConstructor().newInstance(); nt = ntc.getConstructor().newInstance();
ntc.getMethod("setPointer", pc).invoke(nt, pc.getMethod("createConstant", long.class).invoke(null, handle)); ntc.getMethod("setPointer", pc).invoke(nt, pc.getMethod("createConstant", long.class).invoke(null, handle));
return ((Number) k32c.getMethod("GetProcessId", ntc).invoke(k32, nt)).longValue(); return ((Number) k32c.getMethod("GetProcessId", ntc).invoke(k32, nt)).longValue();
} else if (process.getClass().getName().equals("java.lang.UNIXProcess")) { } catch (Throwable e3) {
Object response = Util.reflect(process.getClass().getDeclaredField("pid"), process); // No way to find pid, I suppose.
if (response instanceof Number)
return ((Number) response).longValue();
} }
} catch (Throwable e) {} }
} }
} }
return null; return null;
@ -77,14 +83,16 @@ public class Executable {
*/ */
public static void terminate(Process process) { public static void terminate(Process process) {
if (process.isAlive()) { if (process.isAlive()) {
if (System.getProperty("os.name").toLowerCase().startsWith("windows")) { Long pid = pid(process);
Long pid = pid(process); if (pid != null) try {
if (pid != null) try { if (Platform.getSystem() == Platform.WINDOWS) {
Process terminator = Runtime.getRuntime().exec(new String[]{"taskkill.exe", "/T", "/F", "/PID", pid.toString()}); Runtime.getRuntime().exec(new String[]{"taskkill.exe", "/T", "/F", "/PID", pid.toString()}).waitFor();
terminator.waitFor(); }
} catch (Throwable e) {} } catch (IOException | InterruptedException e) {}
if (process.isAlive()) {
process.destroyForcibly();
} }
if (process.isAlive()) process.destroyForcibly();
} }
} }
} }