jeudi 9 septembre 2021

JDK11 to JDK12 Migration java.lang.NoSuchFieldException: modifiers

Below function Hacks the "HttpURLConnection#methods" static field (through Java Reflection). I am using reflection to unit test my code functionality. I found out we can not change the static final fields in JDK12. I found one solution to use unsafe but I am not sure how can I get this function working in JDK12 using unsafe.

protected static void allowMethods(String... methods) {
    try {
        Field methodsField = HttpURLConnection.class.getDeclaredField("methods");

        Field modifiersField = Unsafe.class.getDeclaredField("modifiers");
        modifiersField.setAccessible(true);
        modifiersField.setInt(methodsField, methodsField.getModifiers() & ~Modifier.FINAL);

        methodsField.setAccessible(true);

        String[] oldMethods = (String[]) methodsField.get(null);
        Set<String> methodsSet = new LinkedHashSet<>(Arrays.asList(oldMethods));
        methodsSet.addAll(Arrays.asList(methods));
        String[] newMethods = methodsSet.toArray(new String[0]);

        methodsField.set(null/*static field*/, newMethods);
    } catch (NoSuchFieldException | IllegalAccessException e) {
        throw new IllegalStateException(e);
    }
}  

This is the stacktrace for the above code:

Caused by: java.lang.IllegalStateException: java.lang.NoSuchFieldException: modifiers
at pii.rest.call.RestUtils.allowMethods(RestUtils.java:75)
at pii.rest.call.JobAbort.<clinit>(JobAbort.java:39)
Caused by: java.lang.NoSuchFieldException: modifiers
at java.base/java.lang.Class.getDeclaredField(Class.java:2549)
at pii.rest.call.RestUtils.allowMethods(RestUtils.java:62)

Can anybody help me convert this function to use Unsafe so therefore it works with JDK12+. I have tried this until now:

final Field ourField = HttpURLConnection.class.getDeclaredField("methods");
final Field unsafeField = Unsafe.class.getDeclaredField("theUnsafe");
unsafeField.setAccessible(true);
final Unsafe unsafe = (Unsafe) unsafeField.get(null);
final Object staticFieldBase = unsafe.staticFieldBase(ourField);
final long staticFieldOffset = unsafe.staticFieldOffset(ourField);
unsafe.putObject(staticFieldBase, staticFieldOffset, "it works");




Aucun commentaire:

Enregistrer un commentaire