mercredi 14 juin 2023

How to obtain a private Lookup?

I've got some piece of code, that is supposed to work with Java 8+. The larger surrounding project is heavily based on Reflection, and should be made ready for Java 9+.

What I am doing now, is this: If I can obtain a private Lookup via MethodHandles.lookup().privateLookupIn(Class), then I am using that private Lookup instead of Reflection. That should be safe for current Java versions, at least to 17, without warnings.

That works, indeed, with one exception: I am getting a warning, when attempting to obtain the private Lookup itself. In other words, the code below emits a warning:

WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access using Lookup on lookup.demo.LookupDemo (file:/C:/Work/ews/4.28/LookupDemo/bin/) to class java.util.HashMap
WARNING: Please consider reporting this to the maintainers of lookup.demo.LookupDemo
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release

In my opinion, the Lookup returned by MethodHandles.publicLookup() should be able with a public class (MethodHandles), thus giving permission to the public method MethodHandles.privateLookupIn?

Thanks,

Jochen

public class LookupDemo {
    public static void main(String[] pArgs) throws Exception {
        System.out.println("Lookup = " +
                           getPrivateLookup(HashMap.class));
    }

    // Note: The following method can still be compiled with Java 8,
    // although it produces a different result.
    private static Lookup getPrivateLookup(Class<?> pType) {
        try {
            // This is supposed to work fine on Java 9+
            final Method method = MethodHandles.class.getDeclaredMethod("privateLookupIn", Class.class, Lookup.class);
            final MethodHandle mh = MethodHandles.publicLookup().unreflect(method);
            return (Lookup) mh.invoke(pType, MethodHandles.lookup());
        } catch (Throwable t) {
            // We are running on Java 8.
            return null;
        }
    }
}




Aucun commentaire:

Enregistrer un commentaire