Skip to content
This repository has been archived by the owner on Jan 24, 2022. It is now read-only.

Commit

Permalink
Fix support for newer Java by using VarHandle to bypass the reflectio…
Browse files Browse the repository at this point in the history
…n blacklist
  • Loading branch information
comp500 committed Jun 26, 2020
1 parent 7080b69 commit 3822cdc
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 15 deletions.
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -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'

Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
modGroup=link.infra.jumploader
modVersion=1.0.8
modVersion=1.0.9
modBaseName=jumploader
2 changes: 1 addition & 1 deletion src/main/java/link/infra/jumploader/Jumploader.java
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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")
Expand Down
2 changes: 1 addition & 1 deletion src/main/resources/fabric.mod.json
Original file line number Diff line number Diff line change
@@ -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.",
Expand Down

0 comments on commit 3822cdc

Please sign in to comment.