From 01b37db0d22c7abe384f55105aa804a5d9cd5c6c Mon Sep 17 00:00:00 2001 From: Gravit Date: Wed, 19 Dec 2018 19:38:32 +0700 Subject: [PATCH] =?UTF-8?q?=D0=9E=D0=B1=D0=BD=D0=BE=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20ServerWrapper=20=D0=A4=D0=B8=D1=82=D1=87?= =?UTF-8?q?=D0=B0=20=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8?= =?UTF-8?q?=D1=8F=20classpath=20=D0=A4=D0=B8=D1=82=D1=87=D0=B0=20=D0=B0?= =?UTF-8?q?=D0=B2=D1=82=D0=BE=D0=B7=D0=B0=D0=B3=D1=80=D1=83=D0=B7=D0=BA?= =?UTF-8?q?=D0=B8=20=D0=B1=D0=B8=D0=B1=D0=BB=D0=B8=D0=BE=D1=82=D0=B5=D0=BA?= =?UTF-8?q?(libraries)=20=D0=9F=D1=80=D0=BE=D0=BA=D1=81=D0=B8=D1=80=D0=BE?= =?UTF-8?q?=D0=B2=D0=B0=D0=BD=D0=B8=D0=B5=20=D0=B0=D0=B3=D0=B5=D0=BD=D1=82?= =?UTF-8?q?=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gravit/launcher/server/ServerAgent.java | 31 ++++++++- .../gravit/launcher/server/ServerWrapper.java | 67 ++++++++++++++----- .../gravit/launcher/server/ServerWrapper.cfg | 9 ++- 3 files changed, 86 insertions(+), 21 deletions(-) diff --git a/ServerWrapper/src/main/java/ru/gravit/launcher/server/ServerAgent.java b/ServerWrapper/src/main/java/ru/gravit/launcher/server/ServerAgent.java index b776f501..57badd80 100644 --- a/ServerWrapper/src/main/java/ru/gravit/launcher/server/ServerAgent.java +++ b/ServerWrapper/src/main/java/ru/gravit/launcher/server/ServerAgent.java @@ -1,9 +1,13 @@ package ru.gravit.launcher.server; +import ru.gravit.utils.helper.IOHelper; import ru.gravit.utils.helper.LogHelper; import java.io.IOException; import java.lang.instrument.Instrumentation; +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; import java.nio.file.*; import java.nio.file.attribute.BasicFileAttributes; import java.util.Collections; @@ -38,14 +42,35 @@ public boolean isAgentStarted() { public static long getObjSize(Object obj) { return inst.getObjectSize(obj); } - + public static Boolean isAutoloadLibraries = Boolean.getBoolean(System.getProperty("serverwrapper,agentlibrariesload","false")); + public static Boolean isAgentProxy = Boolean.getBoolean(System.getProperty("serverwrapper,agentproxy","false")); public static void premain(String agentArgument, Instrumentation instrumentation) { LogHelper.debug("Server Agent"); inst = instrumentation; isAgentStarted = true; - + if(isAutoloadLibraries) + { + Path libraries = Paths.get("libraries"); + if(IOHelper.exists(libraries)) loadLibraries(libraries); + } + if(isAgentProxy) + { + String proxyClassName = System.getProperty("serverwrapper,agentproxyclass"); + Class proxyClass; + try { + proxyClass = Class.forName(proxyClassName); + MethodHandle mainMethod = MethodHandles.publicLookup().findStatic(proxyClass, "premain", MethodType.methodType(void.class, String.class, Instrumentation.class)); + Object[] args = {agentArgument,instrumentation}; + mainMethod.invoke(args); + } catch (Throwable e) { + e.printStackTrace(); + } + } + } + public static void loadLibraries(Path dir) + { try { - Files.walkFileTree(Paths.get("libraries"), Collections.singleton(FileVisitOption.FOLLOW_LINKS), Integer.MAX_VALUE, new StarterVisitor()); + Files.walkFileTree(dir, Collections.singleton(FileVisitOption.FOLLOW_LINKS), Integer.MAX_VALUE, new StarterVisitor()); } catch (IOException e) { e.printStackTrace(System.err); } diff --git a/ServerWrapper/src/main/java/ru/gravit/launcher/server/ServerWrapper.java b/ServerWrapper/src/main/java/ru/gravit/launcher/server/ServerWrapper.java index 1b54ba2a..73fc5a96 100644 --- a/ServerWrapper/src/main/java/ru/gravit/launcher/server/ServerWrapper.java +++ b/ServerWrapper/src/main/java/ru/gravit/launcher/server/ServerWrapper.java @@ -7,8 +7,10 @@ import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodType; +import java.net.URL; import java.nio.file.Path; import java.nio.file.Paths; +import java.util.Arrays; import java.util.HashMap; import ru.gravit.launcher.Launcher; @@ -21,6 +23,7 @@ import ru.gravit.launcher.serialize.config.entry.BooleanConfigEntry; import ru.gravit.launcher.serialize.config.entry.IntegerConfigEntry; import ru.gravit.launcher.serialize.config.entry.StringConfigEntry; +import ru.gravit.utils.PublicURLClassLoader; import ru.gravit.utils.helper.CommonHelper; import ru.gravit.utils.helper.IOHelper; import ru.gravit.utils.helper.LogHelper; @@ -31,8 +34,13 @@ public class ServerWrapper { public static ModulesManager modulesManager; - public static Path configFile; public static Config config; + public static PublicURLClassLoader ucp; + public static ClassLoader loader; + + public static Path modulesDir = Paths.get(System.getProperty("serverwrapper.modulesDir","modules")); + public static Path configFile = Paths.get(System.getProperty("serverwrapper.configFile","ServerWrapper.cfg")); + public static Path publicKeyFile = Paths.get(System.getProperty("serverwrapper.publicKeyFile","public.key")); public static boolean auth(ServerWrapper wrapper) { try { @@ -79,15 +87,14 @@ public static void main(String[] args) throws Throwable { LogHelper.printVersion("ServerWrapper"); LogHelper.printLicense("ServerWrapper"); modulesManager = new ModulesManager(wrapper); - modulesManager.autoload(Paths.get("srv_modules")); //BungeeCord using modules dir + modulesManager.autoload(modulesDir); Launcher.modulesManager = modulesManager; - configFile = Paths.get("ServerWrapper.cfg"); modulesManager.preInitModules(); generateConfigIfNotExists(); try (BufferedReader reader = IOHelper.newReader(configFile)) { config = new Config(TextConfigReader.read(reader, true)); } - LauncherConfig cfg = new LauncherConfig(config.address, config.port, SecurityHelper.toPublicRSAKey(IOHelper.read(Paths.get("public.key"))), new HashMap<>(), config.projectname); + LauncherConfig cfg = new LauncherConfig(config.address, config.port, SecurityHelper.toPublicRSAKey(IOHelper.read(publicKeyFile)), new HashMap<>(), config.projectname); Launcher.setConfig(cfg); if (config.syncAuth) auth(wrapper); else @@ -99,13 +106,36 @@ public static void main(String[] args) throws Throwable { LogHelper.error("MainClass not found. Please set MainClass for ServerWrapper.cfg or first commandline argument"); } Class mainClass; - if (config.customClassLoader) { - @SuppressWarnings("unchecked") - Class classloader_class = (Class) Class.forName(config.classloader); - ClassLoader loader = classloader_class.getConstructor(ClassLoader.class).newInstance(ClassLoader.getSystemClassLoader()); - Thread.currentThread().setContextClassLoader(loader); - mainClass = Class.forName(classname, false, loader); - } else mainClass = Class.forName(classname); + if(config.customClassPath) + { + String[] cp = config.classpath.split(":"); + if(ServerAgent.inst == null) + { + LogHelper.warning("JavaAgent not found. Using URLClassLoader"); + URL[] urls = Arrays.stream(cp).map(Paths::get).map(IOHelper::toURL).toArray(URL[]::new); + ucp = new PublicURLClassLoader(urls); + Thread.currentThread().setContextClassLoader(ucp); + loader = ucp; + } + else + { + LogHelper.info("Found %d custom classpath elements"); + for(String c : cp) + ServerAgent.addJVMClassPath(c); + } + } + if(config.autoloadLibraries) + { + if(ServerAgent.inst == null) + { + throw new UnsupportedOperationException("JavaAgent not found, autoloadLibraries not available"); + } + Path librariesDir = Paths.get(config.librariesDir); + LogHelper.info("Load libraries"); + ServerAgent.loadLibraries(librariesDir); + } + if(loader != null) mainClass = Class.forName(classname,true, loader); + else mainClass = Class.forName(classname); MethodHandle mainMethod = MethodHandles.publicLookup().findStatic(mainClass, "main", MethodType.methodType(void.class, String[].class)); String[] real_args = new String[args.length - 1]; System.arraycopy(args, 1, real_args, 0, args.length - 1); @@ -143,9 +173,11 @@ public static final class Config extends ConfigObject { public int port; public int reconnectCount; public int reconnectSleep; - public boolean customClassLoader; + public boolean customClassPath; + public boolean autoloadLibraries; public boolean syncAuth; - public String classloader; + public String classpath; + public String librariesDir; public String mainclass; public String login; public String password; @@ -158,9 +190,12 @@ protected Config(BlockConfigEntry block) { login = block.getEntryValue("login", StringConfigEntry.class); password = block.getEntryValue("password", StringConfigEntry.class); port = block.getEntryValue("port", IntegerConfigEntry.class); - customClassLoader = block.getEntryValue("customClassLoader", BooleanConfigEntry.class); - if (customClassLoader) - classloader = block.getEntryValue("classloader", StringConfigEntry.class); + customClassPath = block.getEntryValue("customClassPath", BooleanConfigEntry.class); + autoloadLibraries = block.getEntryValue("autoloadLibraries", BooleanConfigEntry.class); + if (customClassPath) + classpath = block.getEntryValue("classpath", StringConfigEntry.class); + if (autoloadLibraries) + librariesDir = block.getEntryValue("librariesDir", StringConfigEntry.class); mainclass = block.getEntryValue("MainClass", StringConfigEntry.class); reconnectCount = block.hasEntry("reconnectCount") ? block.getEntryValue("reconnectCount", IntegerConfigEntry.class) : 1; reconnectSleep = block.hasEntry("reconnectSleep") ? block.getEntryValue("reconnectSleep", IntegerConfigEntry.class) : 30000; diff --git a/ServerWrapper/src/main/resources/ru/gravit/launcher/server/ServerWrapper.cfg b/ServerWrapper/src/main/resources/ru/gravit/launcher/server/ServerWrapper.cfg index 9250a4d4..9b1ce0c7 100644 --- a/ServerWrapper/src/main/resources/ru/gravit/launcher/server/ServerWrapper.cfg +++ b/ServerWrapper/src/main/resources/ru/gravit/launcher/server/ServerWrapper.cfg @@ -1,6 +1,11 @@ title: "xxxx"; -customClassLoader: false; -classloader: "ru.gravit.utils.PublicURLClassLoader"; + +autoloadLibraries: false; +librariesDir: "libraries"; + +customClassPath: false; +classpath: "server.jar"; + MainClass: ""; address: "localhost"; port: 7240;