From 2e60d45c63433f7e55d3180d8f5ae403ca7a389a Mon Sep 17 00:00:00 2001 From: Gravita <12893402+gravit0@users.noreply.github.com> Date: Sun, 26 Nov 2023 15:07:50 +0700 Subject: [PATCH] [FEATURE][EXPERIMENTAL] Support add javafx in LauncherEngineWrapper --- .../pro/gravit/launcher/LauncherEngine.java | 5 ++- .../launcher/LauncherEngineWrapper.java | 36 ++++++++++++++++++- .../gravit/utils/launch/LaunchOptions.java | 1 + .../pro/gravit/utils/launch/ModuleLaunch.java | 30 +++++++++++++--- .../launcher/ClientLauncherWrapper.java | 25 ------------- 5 files changed, 65 insertions(+), 32 deletions(-) diff --git a/Launcher/src/main/java/pro/gravit/launcher/LauncherEngine.java b/Launcher/src/main/java/pro/gravit/launcher/LauncherEngine.java index 04c94de4..6acaa780 100644 --- a/Launcher/src/main/java/pro/gravit/launcher/LauncherEngine.java +++ b/Launcher/src/main/java/pro/gravit/launcher/LauncherEngine.java @@ -105,7 +105,10 @@ public static boolean contains(String[] array, String value) { public static void main(String... args) throws Throwable { JVMHelper.checkStackTrace(LauncherEngineWrapper.class); - JVMHelper.verifySystemProperties(Launcher.class, true); + JVMHelper.verifySystemProperties(Launcher.class, false); + { + LauncherEngine.checkClass(LauncherEngine.class.getClassLoader().getClass()); + } EnvHelper.checkDangerousParams(); //if(!LauncherAgent.isStarted()) throw new SecurityException("JavaAgent not set"); verifyNoAgent(); diff --git a/Launcher/src/main/java/pro/gravit/launcher/LauncherEngineWrapper.java b/Launcher/src/main/java/pro/gravit/launcher/LauncherEngineWrapper.java index 25906d97..a637a571 100644 --- a/Launcher/src/main/java/pro/gravit/launcher/LauncherEngineWrapper.java +++ b/Launcher/src/main/java/pro/gravit/launcher/LauncherEngineWrapper.java @@ -1,8 +1,42 @@ package pro.gravit.launcher; +import pro.gravit.utils.helper.IOHelper; +import pro.gravit.utils.launch.LaunchOptions; +import pro.gravit.utils.launch.ModuleLaunch; + +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; + @LauncherNetworkAPI public class LauncherEngineWrapper { + private static final List modules = new ArrayList<>(); + + static { + modules.add("javafx.base"); + modules.add("javafx.graphics"); + modules.add("javafx.fxml"); + modules.add("javafx.controls"); + modules.add("javafx.media"); + modules.add("javafx.web"); + } public static void main(String[] args) throws Throwable { - LauncherEngine.main(args); + ModuleLaunch launch = new ModuleLaunch(); + LaunchOptions options = new LaunchOptions(); + options.disablePackageDelegateSupport = true; + options.moduleConf = new LaunchOptions.ModuleConf(); + List classpath = new ArrayList<>(); + classpath.add(IOHelper.getCodeSource(LauncherEngine.class)); + var libDirectory = Path.of(System.getProperty("java.home")).resolve("lib"); + for(var moduleName : modules) { + var path = libDirectory.resolve(moduleName.concat(".jar")); + if(Files.exists(path)) { + options.moduleConf.modules.add(moduleName); + options.moduleConf.modulePath.add(path.toAbsolutePath().toString()); + } + } + var control = launch.init(classpath, null, options); + launch.launch(LauncherEngine.class.getName(), null, List.of(args)); } } diff --git a/LauncherCore/src/main/java/pro/gravit/utils/launch/LaunchOptions.java b/LauncherCore/src/main/java/pro/gravit/utils/launch/LaunchOptions.java index f5232739..fa95d0d8 100644 --- a/LauncherCore/src/main/java/pro/gravit/utils/launch/LaunchOptions.java +++ b/LauncherCore/src/main/java/pro/gravit/utils/launch/LaunchOptions.java @@ -7,6 +7,7 @@ public class LaunchOptions { public boolean enableHacks; + public boolean disablePackageDelegateSupport; public ModuleConf moduleConf; diff --git a/LauncherCore/src/main/java11/pro/gravit/utils/launch/ModuleLaunch.java b/LauncherCore/src/main/java11/pro/gravit/utils/launch/ModuleLaunch.java index dea2b3f4..58c69a5c 100644 --- a/LauncherCore/src/main/java11/pro/gravit/utils/launch/ModuleLaunch.java +++ b/LauncherCore/src/main/java11/pro/gravit/utils/launch/ModuleLaunch.java @@ -18,10 +18,7 @@ import java.net.URLClassLoader; import java.nio.file.Path; import java.nio.file.Paths; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.concurrent.ConcurrentHashMap; public class ModuleLaunch implements Launch { @@ -31,8 +28,10 @@ public class ModuleLaunch implements Launch { private ModuleFinder moduleFinder; private ModuleLayer layer; private MethodHandles.Lookup hackLookup; + private boolean disablePackageDelegateSupport; @Override public ClassLoaderControl init(List files, String nativePath, LaunchOptions options) { + this.disablePackageDelegateSupport = options.disablePackageDelegateSupport; moduleClassLoader = new ModuleClassLoader(files.stream().map((e) -> { try { return e.toUri().toURL(); @@ -122,6 +121,7 @@ public ClassLoaderControl init(List files, String nativePath, LaunchOption } } } + moduleClassLoader.initializeWithLayer(layer); } return moduleClassLoader.makeControl(); } @@ -160,6 +160,7 @@ private class ModuleClassLoader extends URLClassLoader { private final ClassLoader SYSTEM_CLASS_LOADER = ClassLoader.getSystemClassLoader(); private final List transformers = new ArrayList<>(); private final Map> classMap = new ConcurrentHashMap<>(); + private final Map packageToModule = new HashMap<>(); private String nativePath; private final List packages = new ArrayList<>(); @@ -169,9 +170,17 @@ public ModuleClassLoader(URL[] urls, ClassLoader parent) { packages.add("pro.gravit.utils."); } + private void initializeWithLayer(ModuleLayer layer) { + for(var m : layer.modules()) { + for(var p : m.getPackages()) { + packageToModule.put(p, m); + } + } + } + @Override protected Class loadClass(String name, boolean resolve) throws ClassNotFoundException { - if(name != null) { + if(name != null && !disablePackageDelegateSupport) { for(String pkg : packages) { if(name.startsWith(pkg)) { return SYSTEM_CLASS_LOADER.loadClass(name); @@ -220,6 +229,17 @@ protected Class findClass(String moduleName, String name) { } } } + if(clazz == null && layer != null && name != null) { + var pkg = getPackageFromClass(name); + var module = packageToModule.get(pkg); + if(module != null) { + try { + clazz = module.getClassLoader().loadClass(name); + } catch (ClassNotFoundException e) { + return null; + } + } + } if(clazz == null) { try { clazz = super.findClass(name); diff --git a/LauncherStart/src/main/java/pro/gravit/launcher/ClientLauncherWrapper.java b/LauncherStart/src/main/java/pro/gravit/launcher/ClientLauncherWrapper.java index 185bbb5f..30e4301b 100644 --- a/LauncherStart/src/main/java/pro/gravit/launcher/ClientLauncherWrapper.java +++ b/LauncherStart/src/main/java/pro/gravit/launcher/ClientLauncherWrapper.java @@ -129,31 +129,6 @@ public static void main(String[] arguments) throws IOException, InterruptedExcep 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 = JavaHelper.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 = JavaHelper.tryAddModule(context.javaFXPaths, moduleName, modulesPath); - if (success) { - if (modulesAdd.length() > 0) modulesAdd.append(","); - modulesAdd.append(moduleName); - } - } - if (modulesAdd.length() > 0) { - args.add("--add-modules"); - args.add(modulesAdd.toString()); - } - if (modulesPath.length() > 0) { - args.add("--module-path"); - args.add(modulesPath.toString()); - } - } if (context.memoryLimit != 0) { args.add(String.format("-Xmx%dM", context.memoryLimit)); }