From 3e654f4d79213d3d5c6d2a1c59c10c92d2d91bf5 Mon Sep 17 00:00:00 2001 From: Gravita <12893402+gravit0@users.noreply.github.com> Date: Sun, 18 Aug 2024 23:10:58 +0700 Subject: [PATCH] [FEATURE] Add support opens, exports, reads to SYSTEM_CLASS_LOADER. Remove AGENT --- Launcher/build.gradle | 2 - .../launcher/runtime/LauncherEngine.java | 1 - .../runtime/client/ClientLauncherProcess.java | 22 ++++++- .../launcher/base/profiles/ClientProfile.java | 2 +- LauncherClient/build.gradle | 4 +- .../client/ClientLauncherEntryPoint.java | 18 ++---- .../gravit/launcher/client/LauncherAgent.java | 59 ------------------- 7 files changed, 25 insertions(+), 83 deletions(-) delete mode 100644 LauncherClient/src/main/java/pro/gravit/launcher/client/LauncherAgent.java diff --git a/Launcher/build.gradle b/Launcher/build.gradle index a2253345..42ed13a7 100644 --- a/Launcher/build.gradle +++ b/Launcher/build.gradle @@ -1,7 +1,6 @@ apply plugin: 'com.github.johnrengelman.shadow' String mainClassName = "pro.gravit.launcher.start.ClientLauncherWrapper" -String mainAgentName = "pro.gravit.launcher.runtime.LauncherAgent" repositories { maven { @@ -20,7 +19,6 @@ jar { archiveClassifier.set('clean') manifest.attributes("Main-Class": mainClassName, - "Premain-Class": mainAgentName, "Multi-Release": "true", "Automatic-Module-Name": "GravitLauncher") } diff --git a/Launcher/src/main/java/pro/gravit/launcher/runtime/LauncherEngine.java b/Launcher/src/main/java/pro/gravit/launcher/runtime/LauncherEngine.java index 8de18308..df1e873b 100644 --- a/Launcher/src/main/java/pro/gravit/launcher/runtime/LauncherEngine.java +++ b/Launcher/src/main/java/pro/gravit/launcher/runtime/LauncherEngine.java @@ -124,7 +124,6 @@ public static void main(String... args) throws Throwable { LogHelper.printLicense("Launcher"); LauncherEngine.checkClass(LauncherEngineWrapper.class); LauncherEngine.checkClass(LauncherEngine.class); - LauncherEngine.checkClass(LauncherAgent.class); LauncherEngine.checkClass(ClientLauncherEntryPoint.class); LauncherEngine.modulesManager = new RuntimeModuleManager(); LauncherEngine.modulesManager.loadModule(new RuntimeLauncherCoreModule()); diff --git a/Launcher/src/main/java/pro/gravit/launcher/runtime/client/ClientLauncherProcess.java b/Launcher/src/main/java/pro/gravit/launcher/runtime/client/ClientLauncherProcess.java index 22b1b843..dc1b5bcd 100644 --- a/Launcher/src/main/java/pro/gravit/launcher/runtime/client/ClientLauncherProcess.java +++ b/Launcher/src/main/java/pro/gravit/launcher/runtime/client/ClientLauncherProcess.java @@ -142,9 +142,7 @@ public void start(boolean pipeOutput) throws IOException, InterruptedException { } //ADD CLASSPATH processArgs.add(JVMHelper.jvmProperty("java.library.path", this.params.nativesDir)); - if (params.profile.getClassLoaderConfig() == ClientProfile.ClassLoaderConfig.AGENT) { - processArgs.add("-javaagent:".concat(IOHelper.getCodeSource(ClientLauncherEntryPoint.class).toAbsolutePath().toString())); - } else if (params.profile.getClassLoaderConfig() == ClientProfile.ClassLoaderConfig.SYSTEM_ARGS) { + if (params.profile.getClassLoaderConfig() == ClientProfile.ClassLoaderConfig.SYSTEM_ARGS) { Set ignorePath = new HashSet<>(); var moduleConf = params.profile.getModuleConf(); if(moduleConf != null) { @@ -159,6 +157,24 @@ public void start(boolean pipeOutput) throws IOException, InterruptedException { processArgs.add("--add-modules"); processArgs.add(String.join(",", moduleConf.modules)); } + if(moduleConf.exports != null && !moduleConf.exports.isEmpty()) { + for(var e : moduleConf.exports.entrySet()) { + processArgs.add("--add-exports"); + processArgs.add(String.format("%s=%s", e.getKey(), e.getValue())); + } + } + if(moduleConf.opens != null && !moduleConf.opens.isEmpty()) { + for(var e : moduleConf.opens.entrySet()) { + processArgs.add("--add-opens"); + processArgs.add(String.format("%s=%s", e.getKey(), e.getValue())); + } + } + if(moduleConf.reads != null && !moduleConf.reads.isEmpty()) { + for(var e : moduleConf.reads.entrySet()) { + processArgs.add("--add-reads"); + processArgs.add(String.format("%s=%s", e.getKey(), e.getValue())); + } + } } systemClassPath.addAll(ClientLauncherEntryPoint.resolveClassPath(ignorePath, workDir, params.actions, params.profile) .map(Path::toString) diff --git a/LauncherAPI/src/main/java/pro/gravit/launcher/base/profiles/ClientProfile.java b/LauncherAPI/src/main/java/pro/gravit/launcher/base/profiles/ClientProfile.java index 0e4bab59..74390d36 100644 --- a/LauncherAPI/src/main/java/pro/gravit/launcher/base/profiles/ClientProfile.java +++ b/LauncherAPI/src/main/java/pro/gravit/launcher/base/profiles/ClientProfile.java @@ -392,7 +392,7 @@ public List getFlags() { } public enum ClassLoaderConfig { - AGENT, LAUNCHER, MODULE, SYSTEM_ARGS + LAUNCHER, MODULE, SYSTEM_ARGS } public enum CompatibilityFlags { diff --git a/LauncherClient/build.gradle b/LauncherClient/build.gradle index 9a59ce29..78ad4310 100644 --- a/LauncherClient/build.gradle +++ b/LauncherClient/build.gradle @@ -1,7 +1,6 @@ apply plugin: 'org.openjfx.javafxplugin' -String mainClassName = "pro.gravit.launcher.ClientLauncherWrapper" -String mainAgentName = "pro.gravit.launcher.LauncherAgent" +String mainClassName = "pro.gravit.launcher.start.ClientLauncherWrapper" repositories { maven { @@ -14,7 +13,6 @@ jar { archiveClassifier.set('clean') manifest.attributes("Main-Class": mainClassName, - "Premain-Class": mainAgentName, "Multi-Release": "true") } diff --git a/LauncherClient/src/main/java/pro/gravit/launcher/client/ClientLauncherEntryPoint.java b/LauncherClient/src/main/java/pro/gravit/launcher/client/ClientLauncherEntryPoint.java index d084f9d5..f767206f 100644 --- a/LauncherClient/src/main/java/pro/gravit/launcher/client/ClientLauncherEntryPoint.java +++ b/LauncherClient/src/main/java/pro/gravit/launcher/client/ClientLauncherEntryPoint.java @@ -86,9 +86,7 @@ private static void realMain(String[] args) throws Throwable { modulesManager.invokeEvent(new PreConfigPhase()); LogHelper.debug("Reading ClientLauncher params"); ClientParams params = readParams(new InetSocketAddress("127.0.0.1", Launcher.getConfig().clientPort)); - if (params.profile.getClassLoaderConfig() != ClientProfile.ClassLoaderConfig.AGENT) { - ClientLauncherMethods.verifyNoAgent(); - } + ClientLauncherMethods.verifyNoAgent(); if(params.timestamp > System.currentTimeMillis() || params.timestamp + 30*1000 < System.currentTimeMillis() ) { LogHelper.error("Timestamp failed. Exit"); ClientLauncherMethods.exitLauncher(-662); @@ -160,7 +158,7 @@ private static void realMain(String[] args) throws Throwable { System.load(Paths.get(params.nativesDir).resolve(ClientService.findLibrary(e)).toAbsolutePath().toString()); } } - if (classLoaderConfig == ClientProfile.ClassLoaderConfig.LAUNCHER) { + if (classLoaderConfig == ClientProfile.ClassLoaderConfig.LAUNCHER || classLoaderConfig == ClientProfile.ClassLoaderConfig.MODULE) { if(JVMHelper.JVM_VERSION <= 11) { launch = new LegacyLaunch(); } else { @@ -170,20 +168,12 @@ private static void realMain(String[] args) throws Throwable { System.setProperty("java.class.path", classpath.stream().map(Path::toString).collect(Collectors.joining(File.pathSeparator))); modulesManager.invokeEvent(new ClientProcessClassLoaderEvent(launch, classLoaderControl, profile)); ClientService.baseURLs = classLoaderControl.getURLs(); - } else if (classLoaderConfig == ClientProfile.ClassLoaderConfig.AGENT) { - launch = new BasicLaunch(LauncherAgent.inst); - classpathURLs.add(IOHelper.getCodeSource(ClientLauncherEntryPoint.class).toUri().toURL()); - classLoaderControl = launch.init(classpath, params.nativesDir, options); - for (URL url : classpathURLs) { - LauncherAgent.addJVMClassPath(Paths.get(url.toURI())); - } - ClientService.instrumentation = LauncherAgent.inst; - modulesManager.invokeEvent(new ClientProcessClassLoaderEvent(launch, null, profile)); - ClientService.baseURLs = classpathURLs.toArray(new URL[0]); } else if (classLoaderConfig == ClientProfile.ClassLoaderConfig.SYSTEM_ARGS) { launch = new BasicLaunch(); classLoaderControl = launch.init(classpath, params.nativesDir, options); ClientService.baseURLs = classpathURLs.toArray(new URL[0]); + } else { + throw new UnsupportedOperationException(String.format("Unknown classLoaderConfig %s", classLoaderConfig)); } if(profile.hasFlag(ClientProfile.CompatibilityFlags.CLASS_CONTROL_API)) { ClientService.classLoaderControl = classLoaderControl; diff --git a/LauncherClient/src/main/java/pro/gravit/launcher/client/LauncherAgent.java b/LauncherClient/src/main/java/pro/gravit/launcher/client/LauncherAgent.java deleted file mode 100644 index 0683af97..00000000 --- a/LauncherClient/src/main/java/pro/gravit/launcher/client/LauncherAgent.java +++ /dev/null @@ -1,59 +0,0 @@ -package pro.gravit.launcher.client; - -import pro.gravit.launcher.client.utils.NativeJVMHalt; -import pro.gravit.utils.helper.LogHelper; - -import java.io.File; -import java.io.IOException; -import java.lang.instrument.Instrumentation; -import java.nio.file.Path; -import java.util.jar.JarFile; - - -public final class LauncherAgent { - public static Instrumentation inst; - private static boolean isAgentStarted = false; - - public static void addJVMClassPath(String path) throws IOException { - LogHelper.debug("Launcher Agent addJVMClassPath"); - inst.appendToSystemClassLoaderSearch(new JarFile(new File(path))); - } - - public static void addJVMClassPath(Path path) throws IOException { - LogHelper.debug("Launcher Agent addJVMClassPath"); - inst.appendToSystemClassLoaderSearch(new JarFile(path.toFile())); - } - - public static void premain(String agentArgument, Instrumentation instrumentation) { - System.out.println("Launcher Agent"); - checkAgentStacktrace(); - inst = instrumentation; - NativeJVMHalt.initFunc(); - isAgentStarted = true; - } - - public static void checkAgentStacktrace() { - RuntimeException ex = new SecurityException("Error check agent stacktrace"); - boolean isFoundNative = false; - boolean foundPreMain = false; - for (StackTraceElement e : ex.getStackTrace()) { - if (e.isNativeMethod()) { - if (!isFoundNative) isFoundNative = true; - else throw ex; - } - if (e.getMethodName().equals("premain")) { - if (!foundPreMain) foundPreMain = true; - else throw ex; - } - } - if (!isFoundNative || !foundPreMain) throw ex; - } - - public static boolean isStarted() { - return isAgentStarted; - } - - public boolean isAgentStarted() { - return isAgentStarted; - } -}