mirror of
https://github.com/ME1312/SubServers-2.git
synced 2025-01-11 02:17:43 +01:00
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:
parent
0d46c5b604
commit
abaa2f3a0e
@ -27,6 +27,12 @@
|
|||||||
<version>1.9-SNAPSHOT</version>
|
<version>1.9-SNAPSHOT</version>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>net.java.dev.jna</groupId>
|
||||||
|
<artifactId>jna-platform</artifactId>
|
||||||
|
<version>5.2.0</version>
|
||||||
|
<scope>compile</scope>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.msgpack</groupId>
|
<groupId>org.msgpack</groupId>
|
||||||
<artifactId>msgpack-core</artifactId>
|
<artifactId>msgpack-core</artifactId>
|
||||||
|
@ -1,6 +1,11 @@
|
|||||||
package net.ME1312.SubServers.Bungee.Host;
|
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.io.File;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Executable String Handler Class
|
* Executable String Handler Class
|
||||||
@ -27,4 +32,58 @@ public class Executable {
|
|||||||
}
|
}
|
||||||
return cmd;
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -358,20 +358,9 @@ public class InternalSubCreator extends SubCreator {
|
|||||||
@Override
|
@Override
|
||||||
public void terminate(String name) {
|
public void terminate(String name) {
|
||||||
if (this.thread.keySet().contains(name.toLowerCase())) {
|
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()) {
|
if (this.thread.get(name.toLowerCase()).process != null && this.thread.get(name.toLowerCase()).process.isAlive()) {
|
||||||
this.thread.get(name.toLowerCase()).process.destroyForcibly();
|
Executable.terminate(this.thread.get(name.toLowerCase()).process);
|
||||||
success = true;
|
} else if (this.thread.get(name.toLowerCase()).isAlive()) {
|
||||||
}
|
|
||||||
|
|
||||||
if (!success && this.thread.get(name.toLowerCase()).isAlive()) {
|
|
||||||
this.thread.get(name.toLowerCase()).interrupt();
|
this.thread.get(name.toLowerCase()).interrupt();
|
||||||
this.thread.remove(name.toLowerCase());
|
this.thread.remove(name.toLowerCase());
|
||||||
}
|
}
|
||||||
|
@ -221,12 +221,7 @@ public class InternalSubServer extends SubServerContainer {
|
|||||||
host.plugin.getPluginManager().callEvent(event);
|
host.plugin.getPluginManager().callEvent(event);
|
||||||
if (!event.isCancelled()) {
|
if (!event.isCancelled()) {
|
||||||
allowrestart = false;
|
allowrestart = false;
|
||||||
if (process != null && process.isAlive() && System.getProperty("os.name").toLowerCase().startsWith("windows")) try {
|
if (process != null && process.isAlive()) Executable.terminate(process);
|
||||||
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();
|
|
||||||
return true;
|
return true;
|
||||||
} else return false;
|
} else return false;
|
||||||
} else return false;
|
} else return false;
|
||||||
|
@ -766,7 +766,7 @@ public final class SubCommand implements CommandExecutor {
|
|||||||
return CommandResult.builder().successCount(0).build();
|
return CommandResult.builder().successCount(0).build();
|
||||||
}
|
}
|
||||||
} else {
|
} 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();
|
return CommandResult.builder().successCount(0).build();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -20,7 +20,13 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>net.ME1312.Galaxi</groupId>
|
<groupId>net.ME1312.Galaxi</groupId>
|
||||||
<artifactId>GalaxiEngine</artifactId>
|
<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>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
|
@ -1,6 +1,11 @@
|
|||||||
package net.ME1312.SubServers.Host.Executable;
|
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.io.File;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Executable String Handler Class
|
* Executable String Handler Class
|
||||||
@ -27,4 +32,58 @@ public class Executable {
|
|||||||
}
|
}
|
||||||
return cmd;
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -382,20 +382,9 @@ public class SubCreator {
|
|||||||
|
|
||||||
public void terminate(String name) {
|
public void terminate(String name) {
|
||||||
if (this.thread.keySet().contains(name.toLowerCase())) {
|
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()) {
|
if (this.thread.get(name.toLowerCase()).process != null && this.thread.get(name.toLowerCase()).process.isAlive()) {
|
||||||
this.thread.get(name.toLowerCase()).process.destroyForcibly();
|
Executable.terminate(this.thread.get(name.toLowerCase()).process);
|
||||||
success = true;
|
} else if (this.thread.get(name.toLowerCase()).isAlive()) {
|
||||||
}
|
|
||||||
|
|
||||||
if (!success && this.thread.get(name.toLowerCase()).isAlive()) {
|
|
||||||
this.thread.get(name.toLowerCase()).interrupt();
|
this.thread.get(name.toLowerCase()).interrupt();
|
||||||
this.thread.remove(name.toLowerCase());
|
this.thread.remove(name.toLowerCase());
|
||||||
}
|
}
|
||||||
|
@ -168,12 +168,7 @@ public class SubServer {
|
|||||||
*/
|
*/
|
||||||
public void terminate() {
|
public void terminate() {
|
||||||
allowrestart = false;
|
allowrestart = false;
|
||||||
if (process != null && process.isAlive() && System.getProperty("os.name").toLowerCase().startsWith("windows")) try {
|
if (process != null && process.isAlive()) Executable.terminate(process);
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user