Add PID termination in Java 8

Some trickery was applied, but its okay since Java 9 has proper API methods for this stuff anyway
This commit is contained in:
ME1312 2019-01-09 12:37:02 -05:00
parent 0d46c5b604
commit abaa2f3a0e
No known key found for this signature in database
GPG Key ID: FEFFE2F698E88FA8
9 changed files with 138 additions and 40 deletions

View File

@ -27,6 +27,12 @@
<version>1.9-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna-platform</artifactId>
<version>5.2.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.msgpack</groupId>
<artifactId>msgpack-core</artifactId>

View File

@ -1,6 +1,11 @@
package net.ME1312.SubServers.Bungee.Host;
import com.sun.jna.Pointer;
import com.sun.jna.platform.win32.Kernel32;
import com.sun.jna.platform.win32.WinNT;
import java.io.File;
import java.lang.reflect.Field;
/**
* Executable String Handler Class
@ -27,4 +32,58 @@ public class Executable {
}
return cmd;
}
/**
* Get the PID of a currently running process
*
* @param process Process
* @return Process ID
*/
public static Long pid(Process process) {
if (process.isAlive()) {
try {
return (long) Process.class.getDeclaredMethod("pid").invoke(process);
} catch (Throwable ex) {
try {
if (process.getClass().getName().equals("java.lang.Win32Process") || process.getClass().getName().equals("java.lang.ProcessImpl")) {
Field f = process.getClass().getDeclaredField("handle");
f.setAccessible(true);
long handle = f.getLong(process);
f.setAccessible(false);
Kernel32 k32 = Kernel32.INSTANCE;
WinNT.HANDLE nt = new WinNT.HANDLE();
nt.setPointer(Pointer.createConstant(handle));
return (long) k32.GetProcessId(nt);
} else if (process.getClass().getName().equals("java.lang.UNIXProcess")) {
Field f = process.getClass().getDeclaredField("pid");
f.setAccessible(true);
Object response = f.get(process);
f.setAccessible(false);
if (response instanceof Number) return ((Number) response).longValue();
}
} catch (Throwable e) {}
}
}
return null;
}
/**
* Terminate a currently running process
*
* @param process Process
*/
public static void terminate(Process process) {
if (process.isAlive()) {
if (System.getProperty("os.name").toLowerCase().startsWith("windows")) {
Long pid = pid(process);
if (pid != null) try {
Process terminator = Runtime.getRuntime().exec(new String[]{"taskkill", "/T", "/F", "/PID", pid.toString()});
terminator.waitFor();
} catch (Throwable e) {}
}
if (process.isAlive()) process.destroyForcibly();
}
}
}

View File

@ -358,20 +358,9 @@ public class InternalSubCreator extends SubCreator {
@Override
public void terminate(String name) {
if (this.thread.keySet().contains(name.toLowerCase())) {
boolean success = false;
if (this.thread.get(name.toLowerCase()).process != null && this.thread.get(name.toLowerCase()).process.isAlive() && System.getProperty("os.name").toLowerCase().startsWith("windows")) try {
Process terminator = Runtime.getRuntime().exec(new String[]{"taskkill", "/T", "/F", "/PID", Long.toString((long) Process.class.getDeclaredMethod("pid").invoke(this.thread.get(name.toLowerCase()).process))});
terminator.waitFor();
if (terminator.exitValue() != 0) throw new IllegalStateException("taskkill exited with code " + terminator.exitValue());
success = true;
} catch (Exception e) {}
if (this.thread.get(name.toLowerCase()).process != null && this.thread.get(name.toLowerCase()).process.isAlive()) {
this.thread.get(name.toLowerCase()).process.destroyForcibly();
success = true;
}
if (!success && this.thread.get(name.toLowerCase()).isAlive()) {
Executable.terminate(this.thread.get(name.toLowerCase()).process);
} else if (this.thread.get(name.toLowerCase()).isAlive()) {
this.thread.get(name.toLowerCase()).interrupt();
this.thread.remove(name.toLowerCase());
}

View File

@ -221,12 +221,7 @@ public class InternalSubServer extends SubServerContainer {
host.plugin.getPluginManager().callEvent(event);
if (!event.isCancelled()) {
allowrestart = false;
if (process != null && process.isAlive() && System.getProperty("os.name").toLowerCase().startsWith("windows")) try {
Process terminator = Runtime.getRuntime().exec(new String[]{"taskkill", "/T", "/F", "/PID", Long.toString((long) Process.class.getDeclaredMethod("pid").invoke(process))});
terminator.waitFor();
if (terminator.exitValue() != 0) throw new IllegalStateException("taskkill exited with code " + terminator.exitValue());
} catch (Exception e) {}
if (process != null && process.isAlive()) process.destroyForcibly();
if (process != null && process.isAlive()) Executable.terminate(process);
return true;
} else return false;
} else return false;

View File

@ -766,7 +766,7 @@ public final class SubCommand implements CommandExecutor {
return CommandResult.builder().successCount(0).build();
}
} else {
sender.sendMessage(ChatColor.convertColor(plugin.api.getLang("SubServers","Command.Generic.Usage").replace("$str$", "/sub stop <SubServer>")));
sender.sendMessage(ChatColor.convertColor(plugin.api.getLang("SubServers","Command.Generic.Usage").replace("$str$", "/sub restart <SubServer>")));
return CommandResult.builder().successCount(0).build();
}
} else {

View File

@ -20,7 +20,13 @@
<dependency>
<groupId>net.ME1312.Galaxi</groupId>
<artifactId>GalaxiEngine</artifactId>
<version>19w02d</version>
<version>19w02e</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna-platform</artifactId>
<version>5.2.0</version>
<scope>compile</scope>
</dependency>
<dependency>

View File

@ -1,6 +1,11 @@
package net.ME1312.SubServers.Host.Executable;
import com.sun.jna.Pointer;
import com.sun.jna.platform.win32.Kernel32;
import com.sun.jna.platform.win32.WinNT;
import java.io.File;
import java.lang.reflect.Field;
/**
* Executable String Handler Class
@ -27,4 +32,58 @@ public class Executable {
}
return cmd;
}
/**
* Get the PID of a currently running process
*
* @param process Process
* @return Process ID
*/
public static Long pid(Process process) {
if (process.isAlive()) {
try {
return (long) Process.class.getDeclaredMethod("pid").invoke(process);
} catch (Throwable ex) {
try {
if (process.getClass().getName().equals("java.lang.Win32Process") || process.getClass().getName().equals("java.lang.ProcessImpl")) {
Field f = process.getClass().getDeclaredField("handle");
f.setAccessible(true);
long handle = f.getLong(process);
f.setAccessible(false);
Kernel32 k32 = Kernel32.INSTANCE;
WinNT.HANDLE nt = new WinNT.HANDLE();
nt.setPointer(Pointer.createConstant(handle));
return (long) k32.GetProcessId(nt);
} else if (process.getClass().getName().equals("java.lang.UNIXProcess")) {
Field f = process.getClass().getDeclaredField("pid");
f.setAccessible(true);
Object response = f.get(process);
f.setAccessible(false);
if (response instanceof Number) return ((Number) response).longValue();
}
} catch (Throwable e) {}
}
}
return null;
}
/**
* Terminate a currently running process
*
* @param process Process
*/
public static void terminate(Process process) {
if (process.isAlive()) {
if (System.getProperty("os.name").toLowerCase().startsWith("windows")) {
Long pid = pid(process);
if (pid != null) try {
Process terminator = Runtime.getRuntime().exec(new String[]{"taskkill", "/T", "/F", "/PID", pid.toString()});
terminator.waitFor();
} catch (Throwable e) {}
}
if (process.isAlive()) process.destroyForcibly();
}
}
}

View File

@ -382,20 +382,9 @@ public class SubCreator {
public void terminate(String name) {
if (this.thread.keySet().contains(name.toLowerCase())) {
boolean success = false;
if (this.thread.get(name.toLowerCase()).process != null && this.thread.get(name.toLowerCase()).process.isAlive() && System.getProperty("os.name").toLowerCase().startsWith("windows")) try {
Process terminator = Runtime.getRuntime().exec(new String[]{"taskkill", "/T", "/F", "/PID", Long.toString((long) Process.class.getDeclaredMethod("pid").invoke(this.thread.get(name.toLowerCase()).process))});
terminator.waitFor();
if (terminator.exitValue() != 0) throw new IllegalStateException("taskkill exited with code " + terminator.exitValue());
success = true;
} catch (Exception e) {}
if (this.thread.get(name.toLowerCase()).process != null && this.thread.get(name.toLowerCase()).process.isAlive()) {
this.thread.get(name.toLowerCase()).process.destroyForcibly();
success = true;
}
if (!success && this.thread.get(name.toLowerCase()).isAlive()) {
Executable.terminate(this.thread.get(name.toLowerCase()).process);
} else if (this.thread.get(name.toLowerCase()).isAlive()) {
this.thread.get(name.toLowerCase()).interrupt();
this.thread.remove(name.toLowerCase());
}

View File

@ -168,12 +168,7 @@ public class SubServer {
*/
public void terminate() {
allowrestart = false;
if (process != null && process.isAlive() && System.getProperty("os.name").toLowerCase().startsWith("windows")) try {
Process terminator = Runtime.getRuntime().exec(new String[]{"taskkill", "/T", "/F", "/PID", Long.toString((long) Process.class.getDeclaredMethod("pid").invoke(process))});
terminator.waitFor();
if (terminator.exitValue() != 0) throw new IllegalStateException("taskkill exited with code " + terminator.exitValue());
} catch (Exception e) {}
if (process != null && process.isAlive()) process.destroyForcibly();
if (process != null && process.isAlive()) Executable.terminate(process);
}
/**