diff --git a/src/main/java/de/tudbut/darkreflection/Strategy.java b/src/main/java/de/tudbut/darkreflection/Strategy.java index 65fff8a..e3087b7 100644 --- a/src/main/java/de/tudbut/darkreflection/Strategy.java +++ b/src/main/java/de/tudbut/darkreflection/Strategy.java @@ -10,7 +10,7 @@ import java.lang.reflect.AccessibleObject; import java.lang.reflect.Field; import java.util.Arrays; -import static de.tudbut.darkreflection.UnsafeProvider.offsetGetter; +import static de.tudbut.darkreflection.UnsafeProvider.compat; // which strategy depends on which? @@ -117,8 +117,8 @@ public class Strategy { }), DarkReflection((owner, field, isStatic, type) -> reflectedFieldStrategy.instance(Arrays.stream(classStrategy.instance(owner).getDeclaredFields()).filter(x -> x.getName().equals(field)).findAny().orElse(null))), Unsafe((owner, field, isStatic, type) -> new UnsafeField<>( - isStatic ? offsetGetter.staticFieldBase(owner, field) : null, - isStatic ? offsetGetter.staticFieldOffset(owner, field) : offsetGetter.objectFieldOffset(owner, field), type)), + isStatic ? compat.staticFieldBase(owner, field) : null, + isStatic ? compat.staticFieldOffset(owner, field) : compat.objectFieldOffset(owner, field), type)), ; private final FieldByNameStrategyProvider backend; diff --git a/src/main/java/de/tudbut/darkreflection/UnsafeProvider.java b/src/main/java/de/tudbut/darkreflection/UnsafeProvider.java index 8690390..cab00c4 100644 --- a/src/main/java/de/tudbut/darkreflection/UnsafeProvider.java +++ b/src/main/java/de/tudbut/darkreflection/UnsafeProvider.java @@ -1,8 +1,8 @@ package de.tudbut.darkreflection; -import de.tudbut.darkreflection.unsafe.BasicOffsetGetter; -import de.tudbut.darkreflection.unsafe.IOffsetGetter; -import de.tudbut.darkreflection.unsafe.InternalUnsafeOffsetGetter; +import de.tudbut.darkreflection.unsafe.BasicUnsafeCompat; +import de.tudbut.darkreflection.unsafe.IUnsafeCompat; +import de.tudbut.darkreflection.unsafe.InternalUnsafeCompat; import sun.misc.Unsafe; import java.lang.reflect.Field; @@ -20,15 +20,15 @@ public class UnsafeProvider { } } - public static IOffsetGetter offsetGetter; + public static IUnsafeCompat compat; static { try { Class c = Class.forName("jdk.internal.misc.Unsafe"); c.getMethod("objectFieldOffset", Class.class, String.class); Object o = DarkMethod.invoke(c.getMethod("getUnsafe"), null); - offsetGetter = new InternalUnsafeOffsetGetter(c, o); + compat = new InternalUnsafeCompat(c, o); } catch (Throwable e) { - offsetGetter = new BasicOffsetGetter(); + compat = new BasicUnsafeCompat(); } } } diff --git a/src/main/java/de/tudbut/darkreflection/unsafe/BasicOffsetGetter.java b/src/main/java/de/tudbut/darkreflection/unsafe/BasicOffsetGetter.java deleted file mode 100644 index 2b22d5e..0000000 --- a/src/main/java/de/tudbut/darkreflection/unsafe/BasicOffsetGetter.java +++ /dev/null @@ -1,39 +0,0 @@ -package de.tudbut.darkreflection.unsafe; - -import de.tudbut.darkreflection.DarkField; - -import java.lang.reflect.Field; - -import static de.tudbut.darkreflection.UnsafeProvider.unsafe; - -public class BasicOffsetGetter implements IOffsetGetter { - @Override - public long objectFieldOffset(Field f) { - return unsafe.objectFieldOffset(f); - } - - @Override - public long objectFieldOffset(Class clazz, String name) { - return unsafe.objectFieldOffset(DarkField.nameToField(clazz, name)); - } - - @Override - public long staticFieldOffset(Field f) { - return unsafe.staticFieldOffset(f); - } - - @Override - public long staticFieldOffset(Class clazz, String name) { - return unsafe.staticFieldOffset(DarkField.nameToField(clazz, name)); - } - - @Override - public Object staticFieldBase(Field f) { - return unsafe.staticFieldBase(f); - } - - @Override - public Object staticFieldBase(Class clazz, String name) { - return unsafe.staticFieldBase(DarkField.nameToField(clazz, name)); - } -} diff --git a/src/main/java/de/tudbut/darkreflection/unsafe/BasicUnsafeCompat.java b/src/main/java/de/tudbut/darkreflection/unsafe/BasicUnsafeCompat.java new file mode 100644 index 0000000..701e47d --- /dev/null +++ b/src/main/java/de/tudbut/darkreflection/unsafe/BasicUnsafeCompat.java @@ -0,0 +1,49 @@ +package de.tudbut.darkreflection.unsafe; + +import de.tudbut.darkreflection.DarkAccessibleObject; +import de.tudbut.darkreflection.DarkField; +import de.tudbut.darkreflection.DarkMethod; +import sun.misc.Unsafe; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.security.ProtectionDomain; + +import static de.tudbut.darkreflection.UnsafeProvider.unsafe; + +public class BasicUnsafeCompat implements IUnsafeCompat { + + @Override + public long objectFieldOffset(Class clazz, String name) { + return unsafe.objectFieldOffset(DarkField.nameToField(clazz, name)); + } + + @Override + public long staticFieldOffset(Class clazz, String name) { + return unsafe.staticFieldOffset(DarkField.nameToField(clazz, name)); + } + + @Override + public Object staticFieldBase(Class clazz, String name) { + return unsafe.staticFieldBase(DarkField.nameToField(clazz, name)); + } + + @Override + public Class defineClass(String name, byte[] bytes) { + try { + Method m = Unsafe.class.getDeclaredMethod("defineClass", String.class, byte[].class, int.class, int.class, ClassLoader.class, ProtectionDomain.class); + DarkAccessibleObject.makeAccessible(m); + return (Class) m.invoke(null, name, bytes, 0, bytes.length, null, null); + } catch (InvocationTargetException e) { + throw new RuntimeException(e.getCause()); + } catch (NoSuchMethodException | IllegalAccessException ignore) { + } + + Method m = DarkMethod.instance(ClassLoader.class, "defineClass0", String.class, byte[].class, int.class, int.class, ProtectionDomain.class); + try { + return DarkMethod.invoke(m, ClassLoader.getSystemClassLoader(), name, bytes, 0, bytes.length, null); + } catch (InvocationTargetException e) { + throw new RuntimeException(e.getCause()); + } + } +} diff --git a/src/main/java/de/tudbut/darkreflection/unsafe/IOffsetGetter.java b/src/main/java/de/tudbut/darkreflection/unsafe/IUnsafeCompat.java similarity index 54% rename from src/main/java/de/tudbut/darkreflection/unsafe/IOffsetGetter.java rename to src/main/java/de/tudbut/darkreflection/unsafe/IUnsafeCompat.java index b5e7434..57eee16 100644 --- a/src/main/java/de/tudbut/darkreflection/unsafe/IOffsetGetter.java +++ b/src/main/java/de/tudbut/darkreflection/unsafe/IUnsafeCompat.java @@ -1,13 +1,8 @@ package de.tudbut.darkreflection.unsafe; -import java.lang.reflect.Field; - -public interface IOffsetGetter { - long objectFieldOffset(Field f); +public interface IUnsafeCompat { long objectFieldOffset(Class clazz, String name); - long staticFieldOffset(Field f); long staticFieldOffset(Class clazz, String name); - - Object staticFieldBase(Field f); Object staticFieldBase(Class clazz, String name); + Class defineClass(String name, byte[] bytes); } diff --git a/src/main/java/de/tudbut/darkreflection/unsafe/InternalUnsafeOffsetGetter.java b/src/main/java/de/tudbut/darkreflection/unsafe/InternalUnsafeCompat.java similarity index 79% rename from src/main/java/de/tudbut/darkreflection/unsafe/InternalUnsafeOffsetGetter.java rename to src/main/java/de/tudbut/darkreflection/unsafe/InternalUnsafeCompat.java index 3b02144..ff46462 100644 --- a/src/main/java/de/tudbut/darkreflection/unsafe/InternalUnsafeOffsetGetter.java +++ b/src/main/java/de/tudbut/darkreflection/unsafe/InternalUnsafeCompat.java @@ -5,12 +5,12 @@ import de.tudbut.darkreflection.DarkMethod; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; -public class InternalUnsafeOffsetGetter extends BasicOffsetGetter { +public class InternalUnsafeCompat extends BasicUnsafeCompat { private final Method objectFieldOffset0; private final Object iUnsafe; - public InternalUnsafeOffsetGetter(Class iUnsafeClass, Object iUnsafe) throws NoSuchMethodException { + public InternalUnsafeCompat(Class iUnsafeClass, Object iUnsafe) throws NoSuchMethodException { this.objectFieldOffset0 = iUnsafeClass.getMethod("objectFieldOffset", Class.class, String.class); this.iUnsafe = iUnsafe; }