diff --git a/build.gradle b/build.gradle index af7eb76..e764ef6 100644 --- a/build.gradle +++ b/build.gradle @@ -13,7 +13,7 @@ apply plugin: 'net.minecraftforge.gradle' apply plugin: 'eclipse' apply plugin: 'maven-publish' -version = '1.0.8' +version = '1.0.9' group = 'link.infra.jumploader' // http://maven.apache.org/guides/mini/guide-naming-conventions.html archivesBaseName = 'jumploader' diff --git a/gradle.properties b/gradle.properties index 70c95e7..317b698 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ modGroup=link.infra.jumploader -modVersion=1.0.8 +modVersion=1.0.9 modBaseName=jumploader diff --git a/src/main/java/link/infra/jumploader/Jumploader.java b/src/main/java/link/infra/jumploader/Jumploader.java index 258870a..e6ef5c8 100644 --- a/src/main/java/link/infra/jumploader/Jumploader.java +++ b/src/main/java/link/infra/jumploader/Jumploader.java @@ -35,7 +35,7 @@ import java.util.Set; public class Jumploader implements ITransformationService { - public static final String VERSION = "1.0.8"; + public static final String VERSION = "1.0.9"; public static final String USER_AGENT = "Jumploader/" + VERSION; private final Logger LOGGER = LogManager.getLogger(); diff --git a/src/main/java/link/infra/jumploader/specialcases/FabricLoaderReflectionHack.java b/src/main/java/link/infra/jumploader/specialcases/FabricLoaderReflectionHack.java index 389aefb..0087afd 100644 --- a/src/main/java/link/infra/jumploader/specialcases/FabricLoaderReflectionHack.java +++ b/src/main/java/link/infra/jumploader/specialcases/FabricLoaderReflectionHack.java @@ -5,6 +5,8 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.VarHandle; import java.lang.reflect.Field; import java.net.URL; import java.net.URLStreamHandler; @@ -15,25 +17,67 @@ public class FabricLoaderReflectionHack implements ReflectionHack { private final Logger LOGGER = LogManager.getLogger(); + private static final double JAVA_VERSION = Double.parseDouble(System.getProperty("java.specification.version", "0")); + + private interface ReflectionVersionHandler { + void setClassLoader(ClassLoader loader) throws NoSuchFieldException, IllegalAccessException; + void resetInstalledProviders() throws NoSuchFieldException, IllegalAccessException; + } + + private static class ReflectionVersionHandler8 implements ReflectionVersionHandler { + @Override + public void setClassLoader(ClassLoader loader) throws NoSuchFieldException, IllegalAccessException { + Field scl = ClassLoader.class.getDeclaredField("scl"); + scl.setAccessible(true); + scl.set(null, loader); + } + + @Override + public void resetInstalledProviders() throws NoSuchFieldException, IllegalAccessException { + Field installedProviders = FileSystemProvider.class.getDeclaredField("installedProviders"); + installedProviders.setAccessible(true); + installedProviders.set(null, null); + Field loadingProviders = FileSystemProvider.class.getDeclaredField("loadingProviders"); + loadingProviders.setAccessible(true); + loadingProviders.set(null, false); + } + } + + @SuppressWarnings("Since15") + private static class ReflectionVersionHandler9 implements ReflectionVersionHandler { + @Override + public void setClassLoader(ClassLoader loader) throws NoSuchFieldException, IllegalAccessException { + VarHandle handle = MethodHandles.privateLookupIn(ClassLoader.class, MethodHandles.lookup()).findStaticVarHandle(ClassLoader.class, "scl", ClassLoader.class); + handle.set(loader); + } + + @Override + public void resetInstalledProviders() throws NoSuchFieldException, IllegalAccessException { + MethodHandles.Lookup lookup = MethodHandles.privateLookupIn(FileSystemProvider.class, MethodHandles.lookup()); + VarHandle installedProviders = lookup.findStaticVarHandle(FileSystemProvider.class, "installedProviders", List.class); + installedProviders.set((Object) null); + VarHandle loadingProviders = lookup.findStaticVarHandle(FileSystemProvider.class, "loadingProviders", boolean.class); + loadingProviders.set(false); + } + } private static void reloadFSHandlers(ClassLoader classLoader) throws NoSuchFieldException, IllegalAccessException { // Attempt to load the jimfs protocol handler (required for jar-in-jar) by hacking around the system classloader - Field scl = ClassLoader.class.getDeclaredField("scl"); - scl.setAccessible(true); - ClassLoader existingLoader = (ClassLoader) scl.get(null); - scl.set(null, classLoader); + ClassLoader existingLoader = ClassLoader.getSystemClassLoader(); + ReflectionVersionHandler handler; + if (JAVA_VERSION > 8) { + handler = new ReflectionVersionHandler9(); + } else { + handler = new ReflectionVersionHandler8(); + } + handler.setClassLoader(classLoader); // Force FileSystemProvider to re-enumerate installed providers - Field installedProviders = FileSystemProvider.class.getDeclaredField("installedProviders"); - installedProviders.setAccessible(true); - installedProviders.set(null, null); - Field loadingProviders = FileSystemProvider.class.getDeclaredField("loadingProviders"); - loadingProviders.setAccessible(true); - loadingProviders.set(null, false); + handler.resetInstalledProviders(); FileSystemProvider.installedProviders(); // Set the system classloader back to the actual system classloader - scl.set(null, existingLoader); + handler.setClassLoader(existingLoader); } @SuppressWarnings("unchecked") diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index de50588..2328f4d 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -1,7 +1,7 @@ { "schemaVersion": 1, "id": "jumploader", - "version": "1.0.8", + "version": "1.0.9", "name": "Jumploader", "description": "Allows the use of Fabric mods in Twitch modpacks, by loading Fabric as if it were a Forge mod.",