Обновление ServerWrapper

Фитча добавления classpath
Фитча автозагрузки библиотек(libraries)
Проксирование агента
This commit is contained in:
Gravit 2018-12-19 19:38:32 +07:00
parent d450a17d58
commit 01b37db0d2
No known key found for this signature in database
GPG key ID: 061981E1E85D3216
3 changed files with 86 additions and 21 deletions

View file

@ -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);
}

View file

@ -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> classloader_class = (Class<ClassLoader>) 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;

View file

@ -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;