Make JNA dependency optional

This commit is contained in:
ME1312 2019-01-09 16:41:37 -05:00
parent abaa2f3a0e
commit 651c61312e
No known key found for this signature in database
GPG Key ID: FEFFE2F698E88FA8
14 changed files with 182 additions and 43 deletions

View File

@ -27,12 +27,6 @@
<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,8 +1,6 @@
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 net.ME1312.SubServers.Bungee.Library.Compatibility.JNA;
import java.io.File;
import java.lang.reflect.Field;
@ -37,7 +35,7 @@ public class Executable {
* Get the PID of a currently running process
*
* @param process Process
* @return Process ID
* @return Process ID (null if unknown)
*/
public static Long pid(Process process) {
if (process.isAlive()) {
@ -51,17 +49,22 @@ public class Executable {
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);
ClassLoader jna = JNA.get();
Class<?> pc = jna.loadClass("com.sun.jna.Pointer"),
ntc = jna.loadClass("com.sun.jna.platform.win32.WinNT$HANDLE"),
k32c = jna.loadClass("com.sun.jna.platform.win32.Kernel32");
Object k32 = k32c.getField("INSTANCE").get(null),
nt = ntc.getConstructor().newInstance();
ntc.getMethod("setPointer", pc).invoke(nt, pc.getMethod("createConstant", long.class).invoke(null, handle));
return ((Number) k32c.getMethod("GetProcessId", ntc).invoke(k32, nt)).longValue();
} 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();
if (response instanceof Number)
return ((Number) response).longValue();
}
} catch (Throwable e) {}
}
@ -79,7 +82,7 @@ public class Executable {
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()});
Process terminator = Runtime.getRuntime().exec(new String[]{"taskkill.exe", "/T", "/F", "/PID", pid.toString()});
terminator.waitFor();
} catch (Throwable e) {}
}

View File

@ -0,0 +1,66 @@
package net.ME1312.SubServers.Bungee.Library.Compatibility;
import com.google.common.io.Resources;
import net.ME1312.SubServers.Bungee.Library.UniversalFile;
import net.ME1312.SubServers.Bungee.SubAPI;
import java.io.FileOutputStream;
import java.net.URL;
import java.net.URLClassLoader;
/**
* Load JNA Library
*/
public class JNA {
private static ClassLoader JNA = null;
private static final String JNA_VERSION = "5.2.0";
private static final String JNA_DOWNLOAD = "https://oss.sonatype.org/service/local/repositories/releases/content/net/java/dev/jna/$1/" + JNA_VERSION + "/$1-" + JNA_VERSION + ".jar";
@SuppressWarnings("deprecation")
public static ClassLoader get() {
if (JNA == null) {
boolean announced = false;
UniversalFile library = new UniversalFile(SubAPI.getInstance().getInternals().dir, "SubServers:Cache:Libraries");
library.mkdirs();
UniversalFile jna = new UniversalFile(library, "JNA.jar");
if (!jna.exists()) {
jna.getParentFile().mkdirs();
if (!jna.exists()) {
System.out.println(">> Downloading JNA Library v" + JNA_VERSION);
try (FileOutputStream fin = new FileOutputStream(jna)) {
Resources.copy(new URL(JNA_DOWNLOAD.replace("$1", "jna")), fin);
} catch (Throwable e) {
jna.delete();
e.printStackTrace();
}
announced = true;
}
}
UniversalFile platform = new UniversalFile(library, "JNA-Platform.jar");
if (!platform.exists()) {
platform.getParentFile().mkdirs();
if (!platform.exists()) {
if (!announced) System.out.println(">> Downloading JNA Library v" + JNA_VERSION);
try (FileOutputStream fin = new FileOutputStream(platform)) {
Resources.copy(new URL(JNA_DOWNLOAD.replace("$1", "jna-platform")), fin);
} catch (Throwable e) {
platform.delete();
e.printStackTrace();
}
}
}
if (jna.exists()) {
System.out.println(">> Loading JNA Library");
try {
JNA = new URLClassLoader(new URL[]{jna.toURI().toURL(), platform.toURI().toURL()});
} catch (Throwable e) {
e.printStackTrace();
throw new IllegalArgumentException("Could not load JNA Library");
}
} else {
throw new IllegalArgumentException("Could not find JNA Library");
}
}
return JNA;
}
}

View File

@ -1,4 +1,4 @@
package net.ME1312.SubServers.Bungee.Library.Compatibility.v1_13;
package net.ME1312.SubServers.Bungee.Library.Compatibility.mc1_13;
import net.ME1312.SubServers.Bungee.Library.NamedContainer;
import net.md_5.bungee.api.CommandSender;

View File

@ -36,7 +36,7 @@ public final class SubCommand extends CommandX {
NamedContainer<SubCommand, CommandX> cmd = new NamedContainer<>(new SubCommand(plugin, command), null);
CommandX now = cmd.name();
//if (plugin.api.getGameVersion()[plugin.api.getGameVersion().length - 1].compareTo(new Version("1.13")) >= 0) { // TODO Future Command Validator API?
// now = new net.ME1312.SubServers.Bungee.Library.Compatibility.v1_13.CommandX(cmd.name());
// now = new net.ME1312.SubServers.Bungee.Library.Compatibility.mc1_13.CommandX(cmd.name());
//}
cmd.set(now);
return cmd;
@ -858,7 +858,7 @@ public final class SubCommand extends CommandX {
NamedContainer<BungeeServer, CommandX> cmd = new NamedContainer<>(new BungeeServer(plugin, command), null);
CommandX now = cmd.name();
//if (plugin.api.getGameVersion()[plugin.api.getGameVersion().length - 1].compareTo(new Version("1.13")) >= 0) { // TODO Future Command Validator API?
// now = new net.ME1312.SubServers.Bungee.Library.Compatibility.v1_13.CommandX(cmd.name());
// now = new net.ME1312.SubServers.Bungee.Library.Compatibility.mc1_13.CommandX(cmd.name());
//}
cmd.set(now);
return cmd;

View File

@ -23,12 +23,6 @@
<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>
<groupId>org.msgpack</groupId>
<artifactId>msgpack-core</artifactId>

View File

@ -1,8 +1,6 @@
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 net.ME1312.SubServers.Host.Library.Compatibility.JNA;
import java.io.File;
import java.lang.reflect.Field;
@ -37,7 +35,7 @@ public class Executable {
* Get the PID of a currently running process
*
* @param process Process
* @return Process ID
* @return Process ID (null if unknown)
*/
public static Long pid(Process process) {
if (process.isAlive()) {
@ -51,17 +49,22 @@ public class Executable {
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);
ClassLoader jna = JNA.get();
Class<?> pc = jna.loadClass("com.sun.jna.Pointer"),
ntc = jna.loadClass("com.sun.jna.platform.win32.WinNT$HANDLE"),
k32c = jna.loadClass("com.sun.jna.platform.win32.Kernel32");
Object k32 = k32c.getField("INSTANCE").get(null),
nt = ntc.getConstructor().newInstance();
ntc.getMethod("setPointer", pc).invoke(nt, pc.getMethod("createConstant", long.class).invoke(null, handle));
return ((Number) k32c.getMethod("GetProcessId", ntc).invoke(k32, nt)).longValue();
} 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();
if (response instanceof Number)
return ((Number) response).longValue();
}
} catch (Throwable e) {}
}
@ -79,7 +82,7 @@ public class Executable {
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()});
Process terminator = Runtime.getRuntime().exec(new String[]{"taskkill.exe", "/T", "/F", "/PID", pid.toString()});
terminator.waitFor();
} catch (Throwable e) {}
}

View File

@ -0,0 +1,69 @@
package net.ME1312.SubServers.Host.Library.Compatibility;
import net.ME1312.Galaxi.Galaxi;
import net.ME1312.Galaxi.Library.Log.Logger;
import net.ME1312.Galaxi.Library.UniversalFile;
import java.io.InputStream;
import java.net.URL;
import java.net.URLClassLoader;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
/**
* Load JNA Library
*/
public class JNA {
private static ClassLoader JNA = null;
private static final String JNA_VERSION = "5.2.0";
private static final String JNA_DOWNLOAD = "https://oss.sonatype.org/service/local/repositories/releases/content/net/java/dev/jna/$1/" + JNA_VERSION + "/$1-" + JNA_VERSION + ".jar";
@SuppressWarnings("deprecation")
public static ClassLoader get() {
if (JNA == null) {
boolean announced = false;
Logger log = new Logger("JNA");
UniversalFile library = new UniversalFile(Galaxi.getInstance().getRuntimeDirectory(), "Cache:Libraries");
library.mkdirs();
UniversalFile jna = new UniversalFile(library, "JNA.jar");
if (!jna.exists()) {
jna.getParentFile().mkdirs();
if (!jna.exists()) {
announced = true;
log.info.println("Downloading JNA Library v" + JNA_VERSION);
try (InputStream in = new URL(JNA_DOWNLOAD.replace("$1", "jna")).openStream()) {
Files.copy(in, jna.toPath(), StandardCopyOption.REPLACE_EXISTING);
} catch (Throwable e) {
jna.delete();
log.error.println(e);
}
}
}
UniversalFile platform = new UniversalFile(library, "JNA-Platform.jar");
if (!platform.exists()) {
platform.getParentFile().mkdirs();
if (!platform.exists()) {
if (!announced) log.info.println("Downloading JNA Library v" + JNA_VERSION);
try (InputStream in = new URL(JNA_DOWNLOAD.replace("$1", "jna-platform")).openStream()) {
Files.copy(in, platform.toPath(), StandardCopyOption.REPLACE_EXISTING);
} catch (Throwable e) {
platform.delete();
log.error.println(e);
}
}
}
if (jna.exists()) {
log.info.println("Loading JNA Library");
try {
JNA = new URLClassLoader(new URL[]{jna.toURI().toURL(), platform.toURI().toURL()});
} catch (Throwable e) {
log.error.println(e);
throw new IllegalArgumentException("Could not load JNA Library");
}
} else {
throw new IllegalArgumentException("Could not find JNA Library");
}
}
return JNA;
}
}

View File

@ -44,7 +44,7 @@ public class PacketDownloadLang implements PacketIn, PacketOut {
f.setAccessible(false);
log.info.println("Lang Settings Downloaded");
} catch (IllegalAccessException | NoSuchFieldException e) {
e.printStackTrace();
log.error.println(e);
}
}

View File

@ -92,7 +92,7 @@ public class PacketExDeleteServer implements PacketIn, PacketOut {
Util.deleteDirectory(from);
}
} catch (Exception e) {
e.printStackTrace();
log.error.println(e);
}
log.info.println("Saving...");
@ -102,7 +102,7 @@ public class PacketExDeleteServer implements PacketIn, PacketOut {
data.getSection("info").toJSON().write(writer);
writer.close();
} catch (Exception e) {
e.printStackTrace();
log.error.println(e);
}
if (UPnP.isUPnPAvailable() && UPnP.isMappedTCP(server.getPort())) UPnP.closePortTCP(server.getPort());
log.info.println("Deleted SubServer: " + data.getRawString("server"));

View File

@ -1,20 +1,30 @@
package net.ME1312.SubServers.Host.Network.Packet;
import net.ME1312.Galaxi.Library.Config.YAMLSection;
import net.ME1312.Galaxi.Library.Log.Logger;
import net.ME1312.Galaxi.Library.Version.Version;
import net.ME1312.SubServers.Host.ExHost;
import net.ME1312.SubServers.Host.Network.PacketIn;
import net.ME1312.SubServers.Host.Network.SubDataClient;
import java.io.IOException;
import java.lang.reflect.Field;
/**
* Reload Packet
*/
public class PacketInReload implements PacketIn {
private ExHost host;
private Logger log;
public PacketInReload(ExHost host) {
this.host = host;
try {
Field f = SubDataClient.class.getDeclaredField("log");
f.setAccessible(true);
this.log = (Logger) f.get(null);
f.setAccessible(false);
} catch (IllegalAccessException | NoSuchFieldException e) {}
}
@Override
@ -22,7 +32,7 @@ public class PacketInReload implements PacketIn {
try {
host.reload();
} catch (IOException e) {
e.printStackTrace();
log.error.println(e);
}
}

View File

@ -58,7 +58,7 @@ public class SubCommand {
commands = (TreeMap<String, Command>) f.get(GalaxiEngine.getInstance().getPluginManager());
f.setAccessible(false);
} catch (Exception e) {
e.printStackTrace();
SubAPI.getInstance().getAppInfo().getLogger().error.println(e);
commands = new TreeMap<String, Command>();
}
if (args.length <= 1) {

View File

@ -1,4 +1,4 @@
package net.ME1312.SubServers.Sync.Library.Compatibility.v1_13;
package net.ME1312.SubServers.Sync.Library.Compatibility.mc1_13;
import net.ME1312.SubServers.Sync.Library.NamedContainer;
import net.md_5.bungee.api.CommandSender;

View File

@ -41,7 +41,7 @@ public final class SubCommand extends CommandX {
NamedContainer<SubCommand, CommandX> cmd = new NamedContainer<>(new SubCommand(plugin, command), null);
CommandX now = cmd.name();
//if (plugin.api.getGameVersion()[plugin.api.getGameVersion().length - 1].compareTo(new Version("1.13")) >= 0) { // TODO Future Command Validator API?
// now = new net.ME1312.SubServers.Sync.Library.Compatibility.v1_13.CommandX(cmd.name());
// now = new net.ME1312.SubServers.Sync.Library.Compatibility.mc1_13.CommandX(cmd.name());
//}
cmd.set(now);
return cmd;
@ -857,7 +857,7 @@ public final class SubCommand extends CommandX {
NamedContainer<BungeeServer, CommandX> cmd = new NamedContainer<>(new BungeeServer(plugin, command), null);
CommandX now = cmd.name();
//if (plugin.api.getGameVersion()[plugin.api.getGameVersion().length - 1].compareTo(new Version("1.13")) >= 0) { // TODO Future Command Validator API?
// now = new net.ME1312.SubServers.Sync.Library.Compatibility.v1_13.CommandX(cmd.name());
// now = new net.ME1312.SubServers.Sync.Library.Compatibility.mc1_13.CommandX(cmd.name());
//}
cmd.set(now);
return cmd;