diff --git a/cacio-tta/pom.xml b/cacio-tta/pom.xml
index ed3134b..6b5eb40 100644
--- a/cacio-tta/pom.xml
+++ b/cacio-tta/pom.xml
@@ -58,6 +58,7 @@
17
-XDignore.symbol.file=true
+ --add-exports=java.base/jdk.internal.misc=ALL-UNNAMED
--add-exports=java.desktop/java.awt.peer=ALL-UNNAMED
--add-exports=java.desktop/sun.awt.image=ALL-UNNAMED
--add-exports=java.desktop/sun.java2d=ALL-UNNAMED
diff --git a/cacio-tta/src/main/java/com/github/caciocavallosilano/cacio/ctc/CTCPreloadClassLoader.java b/cacio-tta/src/main/java/com/github/caciocavallosilano/cacio/ctc/CTCPreloadClassLoader.java
index 39165da..082380b 100644
--- a/cacio-tta/src/main/java/com/github/caciocavallosilano/cacio/ctc/CTCPreloadClassLoader.java
+++ b/cacio-tta/src/main/java/com/github/caciocavallosilano/cacio/ctc/CTCPreloadClassLoader.java
@@ -30,24 +30,10 @@
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Field;
-import java.lang.reflect.Modifier;
-import java.lang.invoke.MethodHandles;
-import java.lang.invoke.VarHandle;
import java.net.*;
+import jdk.internal.misc.Unsafe;
public class CTCPreloadClassLoader extends URLClassLoader {
- // https://stackoverflow.com/a/56043252/1050369
- private static final VarHandle MODIFIERS;
-
- static {
- try {
- var lookup = MethodHandles.privateLookupIn(Field.class, MethodHandles.lookup());
- MODIFIERS = lookup.findVarHandle(Field.class, "modifiers", int.class);
- } catch (IllegalAccessException | NoSuchFieldException ex) {
- throw new RuntimeException(ex);
- }
- }
-
static {
try {
Field toolkit = Toolkit.class.getDeclaredField("toolkit");
@@ -67,12 +53,12 @@ public class CTCPreloadClassLoader extends URLClassLoader {
defaultHeadlessField.set(null, Boolean.FALSE);
headlessField.set(null,Boolean.FALSE);
- makeNonFinal(ge);
-
Class> smfCls = Class.forName("sun.java2d.SurfaceManagerFactory");
Field smf = smfCls.getDeclaredField("instance");
smf.setAccessible(true);
smf.set(null, null);
+
+ setWithUnsafe(ge, new CTCGraphicsEnvironment());
ge.set(null, new CTCGraphicsEnvironment());
@@ -107,7 +93,7 @@ static URL getFileURL(File file) {
} catch (IOException e) {}
try {
- return file.toURL();
+ return file.toURI().toURL();
} catch (MalformedURLException e) {
// Should never happen since we specify the protocol...
throw new InternalError(e);
@@ -119,10 +105,16 @@ private void appendToClassPathForInstrumentation(String path) {
super.addURL(getFileURL(new File(path)));
}
- public static void makeNonFinal(Field field) {
- int mods = field.getModifiers();
- if (Modifier.isFinal(mods)) {
- MODIFIERS.set(field, mods & ~Modifier.FINAL);
- }
+ public static void setWithUnsafe(Field field, Object value) {
+ /*
+ * We can do this because we are running under *very* specific conditions:
+ * - This class is initialized way before anything AWT-related gets JIT-ed
+ * - The field is an object reference.
+ * Otherwise this won't work at all.
+ */
+ Unsafe unsafe = Unsafe.getUnsafe();
+ Object base = unsafe.staticFieldBase(field);
+ long offset = unsafe.staticFieldOffset(field);
+ unsafe.putReference(base, offset, value);
}
}
diff --git a/cacio-tta/src/main/java/com/github/caciocavallosilano/cacio/ctc/junit/CacioTestRunner.java b/cacio-tta/src/main/java/com/github/caciocavallosilano/cacio/ctc/junit/CacioTestRunner.java
index 65613c7..a908c4e 100644
--- a/cacio-tta/src/main/java/com/github/caciocavallosilano/cacio/ctc/junit/CacioTestRunner.java
+++ b/cacio-tta/src/main/java/com/github/caciocavallosilano/cacio/ctc/junit/CacioTestRunner.java
@@ -27,6 +27,7 @@
import javax.swing.plaf.metal.MetalLookAndFeel;
import com.github.caciocavallosilano.cacio.ctc.CTCGraphicsEnvironment;
+import com.github.caciocavallosilano.cacio.ctc.CTCPreloadClassLoader;
import com.github.caciocavallosilano.cacio.ctc.CTCToolkit;
import org.junit.runners.BlockJUnit4ClassRunner;
@@ -34,23 +35,8 @@
import java.awt.*;
import java.lang.reflect.Field;
-import java.lang.reflect.Modifier;
-import java.lang.invoke.MethodHandles;
-import java.lang.invoke.VarHandle;
public class CacioTestRunner extends BlockJUnit4ClassRunner {
- // https://stackoverflow.com/a/56043252/1050369
- private static final VarHandle MODIFIERS;
-
- static {
- try {
- var lookup = MethodHandles.privateLookupIn(Field.class, MethodHandles.lookup());
- MODIFIERS = lookup.findVarHandle(Field.class, "modifiers", int.class);
- } catch (IllegalAccessException | NoSuchFieldException ex) {
- throw new RuntimeException(ex);
- }
- }
-
static {
try {
Field toolkit = Toolkit.class.getDeclaredField("toolkit");
@@ -59,7 +45,7 @@ public class CacioTestRunner extends BlockJUnit4ClassRunner {
Field defaultHeadlessField = java.awt.GraphicsEnvironment.class.getDeclaredField("defaultHeadless");
defaultHeadlessField.setAccessible(true);
- defaultHeadlessField.set(null,Boolean.TRUE);
+ defaultHeadlessField.set(null,Boolean.TRUE);
Field headlessField = java.awt.GraphicsEnvironment.class.getDeclaredField("headless");
headlessField.setAccessible(true);
headlessField.set(null,Boolean.TRUE);
@@ -70,14 +56,13 @@ public class CacioTestRunner extends BlockJUnit4ClassRunner {
defaultHeadlessField.set(null, Boolean.FALSE);
headlessField.set(null,Boolean.FALSE);
- makeNonFinal(ge);
Class> smfCls = Class.forName("sun.java2d.SurfaceManagerFactory");
Field smf = smfCls.getDeclaredField("instance");
smf.setAccessible(true);
smf.set(null, null);
- ge.set(null, new CTCGraphicsEnvironment());
+ CTCPreloadClassLoader.setWithUnsafe(ge, new CTCGraphicsEnvironment());
} catch (Exception e) {
e.printStackTrace();
}
@@ -88,11 +73,4 @@ public class CacioTestRunner extends BlockJUnit4ClassRunner {
public CacioTestRunner(Class> klass) throws InitializationError {
super(klass);
}
-
- public static void makeNonFinal(Field field) {
- int mods = field.getModifiers();
- if (Modifier.isFinal(mods)) {
- MODIFIERS.set(field, mods & ~Modifier.FINAL);
- }
- }
}
diff --git a/pom.xml b/pom.xml
index f7c49ba..2703bc5 100644
--- a/pom.xml
+++ b/pom.xml
@@ -59,6 +59,7 @@
-XDignore.symbol.file=true
+ --add-exports=java.base/jdk.internal.misc=ALL-UNNAMED
--add-exports=java.desktop/java.awt.peer=ALL-UNNAMED
--add-exports=java.desktop/sun.awt=ALL-UNNAMED
--add-exports=java.desktop/sun.awt.event=ALL-UNNAMED
@@ -130,6 +131,7 @@
false
+ --add-exports=java.base/jdk.internal.misc=ALL-UNNAMED
--add-exports=java.desktop/java.awt=ALL-UNNAMED
--add-exports=java.desktop/java.awt.peer=ALL-UNNAMED
--add-exports=java.desktop/sun.awt.image=ALL-UNNAMED