3030import java .io .File ;
3131import java .io .IOException ;
3232import java .lang .reflect .Field ;
33+ import java .lang .reflect .Method ;
3334import java .lang .reflect .Modifier ;
3435import java .lang .invoke .MethodHandles ;
3536import java .lang .invoke .VarHandle ;
3637import java .net .*;
38+ import java .util .Arrays ;
39+ import java .util .Objects ;
40+ import sun .misc .Unsafe ;
3741
3842public class CTCPreloadClassLoader extends URLClassLoader {
39- // https://stackoverflow.com/a/56043252/1050369
40- private static final VarHandle MODIFIERS ;
41-
42- static {
43- try {
44- var lookup = MethodHandles .privateLookupIn (Field .class , MethodHandles .lookup ());
45- MODIFIERS = lookup .findVarHandle (Field .class , "modifiers" , int .class );
46- } catch (IllegalAccessException | NoSuchFieldException ex ) {
47- throw new RuntimeException (ex );
48- }
49- }
50-
5143 static {
5244 try {
5345 Field toolkit = Toolkit .class .getDeclaredField ("toolkit" );
@@ -67,14 +59,12 @@ public class CTCPreloadClassLoader extends URLClassLoader {
6759 defaultHeadlessField .set (null , Boolean .FALSE );
6860 headlessField .set (null ,Boolean .FALSE );
6961
70- makeNonFinal (ge );
71-
7262 Class <?> smfCls = Class .forName ("sun.java2d.SurfaceManagerFactory" );
7363 Field smf = smfCls .getDeclaredField ("instance" );
7464 smf .setAccessible (true );
7565 smf .set (null , null );
7666
77- ge . set ( null , new CTCGraphicsEnvironment ());
67+ setFinalStatic ( ge , new CTCGraphicsEnvironment ());
7868
7969 String propertyFontManager = System .getProperty ("cacio.font.fontmanager" );
8070 if (propertyFontManager != null ) {
@@ -119,10 +109,14 @@ private void appendToClassPathForInstrumentation(String path) {
119109 super .addURL (getFileURL (new File (path )));
120110 }
121111
122- public static void makeNonFinal (Field field ) {
123- int mods = field .getModifiers ();
124- if (Modifier .isFinal (mods )) {
125- MODIFIERS .set (field , mods & ~Modifier .FINAL );
126- }
112+ // https://stackoverflow.com/a/71465198
113+ public static void setFinalStatic (Field field , Object value ) throws Exception {
114+ Field unsafeField = Unsafe .class .getDeclaredField ("theUnsafe" );
115+ unsafeField .setAccessible (true );
116+ Unsafe unsafe = (Unsafe ) unsafeField .get (null );
117+ Object fieldBase = unsafe .staticFieldBase (field );
118+ long fieldOffset = unsafe .staticFieldOffset (field );
119+
120+ unsafe .putObject (fieldBase , fieldOffset , value );
127121 }
128122}
0 commit comments