From 5bff221e7e98a490494ed7e18e5d1360d16cc53b Mon Sep 17 00:00:00 2001 From: Gravita Date: Thu, 15 Apr 2021 22:02:30 +0700 Subject: [PATCH] [FEATURE] ClientLauncherWrapper reworked --- .../launcher/ClientLauncherWrapper.java | 154 ++++++++++++------ .../launcher/client/ClientModuleManager.java | 5 +- .../launcher/client/ClientWrapperModule.java | 4 +- 3 files changed, 111 insertions(+), 52 deletions(-) diff --git a/Launcher/src/main/java/pro/gravit/launcher/ClientLauncherWrapper.java b/Launcher/src/main/java/pro/gravit/launcher/ClientLauncherWrapper.java index 507315bb..b653cba6 100644 --- a/Launcher/src/main/java/pro/gravit/launcher/ClientLauncherWrapper.java +++ b/Launcher/src/main/java/pro/gravit/launcher/ClientLauncherWrapper.java @@ -10,11 +10,10 @@ import java.io.File; import java.io.IOException; +import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; -import java.util.LinkedList; -import java.util.List; -import java.util.Properties; +import java.util.*; public class ClientLauncherWrapper { public static final String MAGIC_ARG = "-Djdk.attach.allowAttachSelf"; @@ -51,66 +50,84 @@ public static void main(String[] arguments) throws IOException, InterruptedExcep if (LogHelper.isDebugEnabled()) waitProcess = true; } LogHelper.info("Restart Launcher with JavaAgent..."); - ProcessBuilder processBuilder = new ProcessBuilder(); - if (waitProcess) processBuilder.inheritIO(); + ClientLauncherWrapperContext context = new ClientLauncherWrapperContext(); + context.processBuilder = new ProcessBuilder(); + if (waitProcess) context.processBuilder.inheritIO(); - JavaVersion javaVersion = null; + context.javaVersion = null; try { - if (!noJavaCheck) javaVersion = findJava(); + if (!noJavaCheck) context.javaVersion = findJava(); } catch (Throwable e) { LogHelper.error(e); } - if (javaVersion == null) { - javaVersion = JavaVersion.getCurrentJavaVersion(); + if (context.javaVersion == null) { + context.javaVersion = JavaVersion.getCurrentJavaVersion(); } - Path javaBin = IOHelper.resolveJavaBin(javaVersion.jvmDir); - List args = new LinkedList<>(); - args.add(javaBin.toString()); + context.executePath = IOHelper.resolveJavaBin(context.javaVersion.jvmDir); + //List args = new LinkedList<>(); + //args.add(javaBin.toString()); String pathLauncher = IOHelper.getCodeSource(LauncherEngine.class).toString(); - args.add(JVMHelper.jvmProperty(LogHelper.DEBUG_PROPERTY, Boolean.toString(LogHelper.isDebugEnabled()))); - args.add(JVMHelper.jvmProperty(LogHelper.STACKTRACE_PROPERTY, Boolean.toString(LogHelper.isStacktraceEnabled()))); - args.add(JVMHelper.jvmProperty(LogHelper.DEV_PROPERTY, Boolean.toString(LogHelper.isDevEnabled()))); - args.add(JVMHelper.jvmProperty("launcher.noSlf4j", "true")); //TODO: Normal fix - JVMHelper.addSystemPropertyToArgs(args, DirBridge.CUSTOMDIR_PROPERTY); - JVMHelper.addSystemPropertyToArgs(args, DirBridge.USE_CUSTOMDIR_PROPERTY); - JVMHelper.addSystemPropertyToArgs(args, DirBridge.USE_OPTDIR_PROPERTY); - JVMHelper.addSystemPropertyToArgs(args, DirWatcher.IGN_OVERFLOW); - if (javaVersion.version >= 9) { - LogHelper.debug("Found Java 9+ ( %s )", System.getProperty("java.version")); - String pathToFx = System.getenv("PATH_TO_FX"); - Path fxPath = pathToFx == null ? null : Paths.get(pathToFx); - StringBuilder builder = new StringBuilder(); - Path[] findPath = new Path[]{javaVersion.jvmDir, javaVersion.jvmDir.resolve("jre"), fxPath}; - tryAddModule(findPath, "javafx.base", builder); - tryAddModule(findPath, "javafx.graphics", builder); - tryAddModule(findPath, "javafx.fxml", builder); - tryAddModule(findPath, "javafx.controls", builder); - boolean useSwing = tryAddModule(findPath, "javafx.swing", builder); - String modulePath = builder.toString(); - if (!modulePath.isEmpty()) { + context.mainClass = LauncherEngine.class.getName(); + context.memoryLimit = launcherMemoryLimit; + context.classpath.add(pathLauncher); + context.jvmProperties.put(LogHelper.DEBUG_PROPERTY, Boolean.toString(LogHelper.isDebugEnabled())); + context.jvmProperties.put(LogHelper.STACKTRACE_PROPERTY, Boolean.toString(LogHelper.isStacktraceEnabled())); + context.jvmProperties.put(LogHelper.DEV_PROPERTY, Boolean.toString(LogHelper.isDevEnabled())); + context.jvmProperties.put("launcher.noSlf4j", "true"); //TODO: Normal fix + context.addSystemProperty(DirBridge.CUSTOMDIR_PROPERTY); + context.addSystemProperty(DirBridge.USE_CUSTOMDIR_PROPERTY); + context.addSystemProperty(DirBridge.USE_OPTDIR_PROPERTY); + context.addSystemProperty(DirWatcher.IGN_OVERFLOW); + context.jvmModules.add("javafx.base"); + context.jvmModules.add("javafx.graphics"); + context.jvmModules.add("javafx.fxml"); + context.jvmModules.add("javafx.controls"); + context.jvmModules.add("javafx.swing"); + context.args.add(MAGIC_ARG); + context.args.add("-XX:+DisableAttachMechanism"); + EnvHelper.addEnv(context.processBuilder); + LauncherEngine.modulesManager.callWrapper(context); + // --------- + List args = new ArrayList<>(16); + args.add(context.executePath.toAbsolutePath().toString()); + args.addAll(context.args); + context.jvmProperties.forEach((key,value) -> args.add(String.format("-D%s=%s", key, value))); + if(context.javaVersion.version >= 9) { + context.javaFXPaths.add(context.javaVersion.jvmDir); + context.javaFXPaths.add(context.javaVersion.jvmDir.resolve("jre")); + Path openjfxPath = tryGetOpenJFXPath(context.javaVersion.jvmDir); + if(openjfxPath != null) { + context.javaFXPaths.add(openjfxPath); + } + StringBuilder modulesPath = new StringBuilder(); + StringBuilder modulesAdd = new StringBuilder(); + for(String moduleName : context.jvmModules) { + boolean success = tryAddModule(context.javaFXPaths, moduleName, modulesPath); + if(success) { + if(modulesAdd.length() > 0) modulesAdd.append(","); + modulesAdd.append(moduleName); + } + } + if(modulesAdd.length() > 0) { args.add("--add-modules"); - String javaModules = "javafx.base,javafx.fxml,javafx.controls,jdk.unsupported"; - if (useSwing) javaModules = javaModules.concat(",javafx.swing"); - args.add(javaModules); + args.add(modulesAdd.toString()); + } + if(modulesPath.length() > 0) { args.add("--module-path"); - args.add(modulePath); + args.add(modulesPath.toString()); } } - args.add(MAGIC_ARG); - args.add("-XX:+DisableAttachMechanism"); - if (launcherMemoryLimit != 0) { - args.add(String.format("-Xmx%dM", launcherMemoryLimit)); + if (context.memoryLimit != 0) { + args.add(String.format("-Xmx%dM", context.memoryLimit)); } - //Collections.addAll(args, "-javaagent:".concat(pathLauncher)); args.add("-cp"); - args.add(pathLauncher); - args.add(LauncherEngine.class.getName()); - LauncherEngine.modulesManager.callWrapper(processBuilder, args); - EnvHelper.addEnv(processBuilder); + args.add(String.join(IOHelper.PLATFORM_SEPARATOR, context.classpath)); + args.add(context.mainClass); + args.addAll(context.clientArgs); LogHelper.debug("Commandline: " + args); - processBuilder.command(args); - Process process = processBuilder.start(); + context.processBuilder.command(args); + Process process = context.processBuilder.start(); if (!waitProcess) { Thread.sleep(3000); if (!process.isAlive()) { @@ -127,6 +144,27 @@ public static void main(String[] arguments) throws IOException, InterruptedExcep } } + public static Path tryGetOpenJFXPath(Path jvmDir) { + String dirName = jvmDir.getFileName().toString(); + Path parent = jvmDir.getParent(); + if(parent == null) return null; + Path archJFXPath = parent.resolve(dirName.replace("openjdk", "openjfx")); + if(Files.isDirectory(archJFXPath)) { + return archJFXPath; + } + Path arch2JFXPath = parent.resolve(dirName.replace("jdk", "openjfx")); + if(Files.isDirectory(arch2JFXPath)) { + return arch2JFXPath; + } + if(JVMHelper.OS_TYPE == JVMHelper.OS.LINUX) { + Path debianJfxPath = Paths.get("/usr/share/openjfx"); + if(Files.isDirectory(debianJfxPath)) { + return debianJfxPath; + } + } + return null; + } + public static Path tryFindModule(Path path, String moduleName) { Path result = path.resolve(moduleName.concat(".jar")); LogHelper.dev("Try resolve %s", result.toString()); @@ -138,7 +176,7 @@ public static Path tryFindModule(Path path, String moduleName) { else return result; } - public static boolean tryAddModule(Path[] paths, String moduleName, StringBuilder args) { + public static boolean tryAddModule(List paths, String moduleName, StringBuilder args) { for (Path path : paths) { if (path == null) continue; Path result = tryFindModule(path, moduleName); @@ -248,4 +286,22 @@ public static boolean isExistExtJavaLibrary(Path jvmDir, String name) { return IOHelper.isFile(jrePath) || IOHelper.isFile(jdkPath); } } + public static class ClientLauncherWrapperContext { + public JavaVersion javaVersion; + public Path executePath; + public String mainClass; + public int memoryLimit; + public ProcessBuilder processBuilder; + public List args = new ArrayList<>(8); + public Map jvmProperties = new HashMap<>(); + public List classpath = new ArrayList<>(); + public List jvmModules = new ArrayList<>(); + public List clientArgs = new ArrayList<>(); + public List javaFXPaths = new ArrayList<>(); + public void addSystemProperty(String name) { + String property = System.getProperty(name); + if (property != null) + jvmProperties.put(name, property); + } + } } diff --git a/Launcher/src/main/java/pro/gravit/launcher/client/ClientModuleManager.java b/Launcher/src/main/java/pro/gravit/launcher/client/ClientModuleManager.java index 3b9d759c..567b8e04 100644 --- a/Launcher/src/main/java/pro/gravit/launcher/client/ClientModuleManager.java +++ b/Launcher/src/main/java/pro/gravit/launcher/client/ClientModuleManager.java @@ -1,5 +1,6 @@ package pro.gravit.launcher.client; +import pro.gravit.launcher.ClientLauncherWrapper; import pro.gravit.launcher.Launcher; import pro.gravit.launcher.LauncherTrustManager; import pro.gravit.launcher.modules.LauncherModule; @@ -33,10 +34,10 @@ public final boolean verifyClassCheckResult(LauncherTrustManager.CheckClassResul return result.type == LauncherTrustManager.CheckClassResultType.SUCCESS; } - public void callWrapper(ProcessBuilder processBuilder, Collection jvmArgs) { + public void callWrapper(ClientLauncherWrapper.ClientLauncherWrapperContext context) { for (LauncherModule module : modules) { if (module instanceof ClientWrapperModule) { - ((ClientWrapperModule) module).wrapperPhase(processBuilder, jvmArgs); + ((ClientWrapperModule) module).wrapperPhase(context); } } } diff --git a/Launcher/src/main/java/pro/gravit/launcher/client/ClientWrapperModule.java b/Launcher/src/main/java/pro/gravit/launcher/client/ClientWrapperModule.java index 4381e6e0..4c55f629 100644 --- a/Launcher/src/main/java/pro/gravit/launcher/client/ClientWrapperModule.java +++ b/Launcher/src/main/java/pro/gravit/launcher/client/ClientWrapperModule.java @@ -1,7 +1,9 @@ package pro.gravit.launcher.client; +import pro.gravit.launcher.ClientLauncherWrapper; + import java.util.Collection; public interface ClientWrapperModule { - void wrapperPhase(ProcessBuilder processBuilder, Collection jvmArgs); + void wrapperPhase(ClientLauncherWrapper.ClientLauncherWrapperContext context); }