mirror of
https://github.com/ME1312/SubServers-2.git
synced 2025-01-10 18:07:54 +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>
|
||||
<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>
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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());
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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 {
|
||||
|
@ -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>
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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());
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user