fix #861: Unable open zipfs for signed exe file

This commit is contained in:
Glavo
2021-05-25 14:27:01 +08:00
committed by Yuhui Huang
parent 66889cac27
commit 0ae1411f0a

View File

@@ -1,22 +1,14 @@
package org.jackhuang.hmcl.util; package org.jackhuang.hmcl.util;
import java.io.InputStream;
import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType; import java.lang.invoke.MethodType;
import java.lang.module.Configuration; import java.lang.module.Configuration;
import java.lang.module.ModuleFinder; import java.lang.module.ModuleFinder;
import java.lang.module.ModuleReference; import java.lang.module.ModuleReference;
import java.net.URI;
import java.nio.file.FileSystem;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.jar.Attributes;
import java.util.jar.Manifest;
import jdk.internal.loader.BuiltinClassLoader; import jdk.internal.loader.BuiltinClassLoader;
@@ -26,6 +18,26 @@ import jdk.internal.loader.BuiltinClassLoader;
* @author ZekerZhayard * @author ZekerZhayard
*/ */
public class JavaFXPatcher { public class JavaFXPatcher {
private static final String[] addOpens = {
"javafx.base/com.sun.javafx.runtime",
"javafx.base/com.sun.javafx.binding",
"javafx.base/com.sun.javafx.event",
"javafx.graphics/javafx.css",
"javafx.graphics/com.sun.javafx.stage",
"javafx.controls/com.sun.javafx.scene.control.behavior",
"javafx.controls/javafx.scene.control.skin",
"javafx.controls/com.sun.javafx.scene.control"
};
private static final String[] addExports = {
"javafx.base/com.sun.javafx.binding",
"javafx.base/com.sun.javafx.event",
"javafx.graphics/com.sun.javafx.stage",
"javafx.controls/com.sun.javafx.scene.control.behavior",
"javafx.controls/javafx.scene.control.skin",
"javafx.controls/com.sun.javafx.scene.control"
};
/** /**
* Add JavaFX to module path at runtime. * Add JavaFX to module path at runtime.
* *
@@ -47,24 +59,19 @@ public class JavaFXPatcher {
ModuleLayer layer = ModuleLayer.defineModules(config, List.of(ModuleLayer.boot()), name -> ClassLoader.getSystemClassLoader()).layer(); ModuleLayer layer = ModuleLayer.defineModules(config, List.of(ModuleLayer.boot()), name -> ClassLoader.getSystemClassLoader()).layer();
// Add-Exports and Add-Opens // Add-Exports and Add-Opens
try ( try {
FileSystem fs = FileSystems.newFileSystem(URI.create("jar:" + JavaFXPatcher.class.getProtectionDomain().getCodeSource().getLocation().toURI()), Map.of("create", "true"));
InputStream stream = Files.newInputStream(fs.getPath("/META-INF/MANIFEST.MF"))
) {
// Some hacks // Some hacks
MethodHandles.Lookup lookup = MethodHandles.privateLookupIn(Module.class, MethodHandles.lookup()); MethodHandles.Lookup lookup = MethodHandles.privateLookupIn(Module.class, MethodHandles.lookup());
Attributes attributes = new Manifest(stream).getMainAttributes(); addExportsOrOpens(addExports, layer, lookup.findVirtual(Module.class, "implAddExportsToAllUnnamed", MethodType.methodType(void.class, String.class)));
addExportsOrOpens(attributes.getValue("Add-Exports"), layer, lookup.findVirtual(Module.class, "implAddExportsToAllUnnamed", MethodType.methodType(void.class, String.class))); addExportsOrOpens(addOpens, layer, lookup.findVirtual(Module.class, "implAddOpensToAllUnnamed", MethodType.methodType(void.class, String.class)));
addExportsOrOpens(attributes.getValue("Add-Opens"), layer, lookup.findVirtual(Module.class, "implAddOpensToAllUnnamed", MethodType.methodType(void.class, String.class)));
} catch (Throwable t) { } catch (Throwable t) {
throw new ReflectiveOperationException(t); throw new ReflectiveOperationException(t);
} }
} }
private static void addExportsOrOpens(String targets, ModuleLayer layer, MethodHandle handle) { private static void addExportsOrOpens(String[] targets, ModuleLayer layer, MethodHandle handle) {
for (String target : targets.split("\\s+")) { for (String target : targets) {
String[] name = target.split("/", 2); // <module>/<package> String[] name = target.split("/", 2); // <module>/<package>
if (name[0].startsWith("javafx.")) {
layer.findModule(name[0]).ifPresent(m -> { layer.findModule(name[0]).ifPresent(m -> {
try { try {
handle.invokeWithArguments(m, name[1]); handle.invokeWithArguments(m, name[1]);
@@ -75,4 +82,3 @@ public class JavaFXPatcher {
} }
} }
} }
}