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

Commit

Permalink
change: Simplify class define tool to call java 16's api explicitly (#42
Browse files Browse the repository at this point in the history
)

Co-authored-by: liach <[email protected]>
  • Loading branch information
liach and liach authored Jul 15, 2021
1 parent db37ae1 commit e64d970
Showing 1 changed file with 5 additions and 26 deletions.
Original file line number Diff line number Diff line change
@@ -1,40 +1,18 @@
package me.jellysquid.mods.hydrogen.common.jvm;

import jdk.dynalink.linker.support.Lookup;
import org.apache.commons.io.IOUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.io.IOException;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.net.URL;

public class ClassDefineTool {
private static final MethodHandles.Lookup LOOKUP;

private static final MethodHandle DEFINE_CLASS_METHOD;
private static final MethodHandle PRIVATE_LOOKUP_IN_METHOD;
private static final MethodHandles.Lookup LOOKUP = MethodHandles.lookup();

private static final Logger LOGGER = LogManager.getLogger("Hydrogen");

static {
LOOKUP = MethodHandles.lookup();

try {
PRIVATE_LOOKUP_IN_METHOD = LOOKUP.findStatic(MethodHandles.class, "privateLookupIn",
MethodType.methodType(MethodHandles.Lookup.class, Class.class, MethodHandles.Lookup.class));

DEFINE_CLASS_METHOD = LOOKUP.findVirtual(MethodHandles.Lookup.class, "defineClass",
MethodType.methodType(Class.class, byte[].class));
} catch (IllegalAccessException e) {
throw new RuntimeException("Couldn't access method", e);
} catch (NoSuchMethodException e) {
throw new RuntimeException("Couldn't locate method", e);
}
}

public static Class<?> defineClass(Class<?> context, String name) {
String path = "/" + name.replace('.', '/') + ".class";
URL url = ClassDefineTool.class.getResource(path);
Expand All @@ -54,9 +32,10 @@ public static Class<?> defineClass(Class<?> context, String name) {
}

try {
MethodHandles.Lookup privateLookup = (MethodHandles.Lookup) PRIVATE_LOOKUP_IN_METHOD.invokeExact((Class<?>) context, (MethodHandles.Lookup) LOOKUP);

return (Class<?>) DEFINE_CLASS_METHOD.invokeExact(privateLookup, (byte[]) code);
// The context class need to be in a module that exports and opens to ClassDefineTool
// Example: guava's automatic module exports and opens to everything
MethodHandles.Lookup privateLookup = MethodHandles.privateLookupIn(context, LOOKUP);
return privateLookup.defineClass(code);
} catch (Throwable throwable) {
throw new RuntimeException("Failed to define class", throwable);
}
Expand Down

0 comments on commit e64d970

Please sign in to comment.