Search code examples
javajava-9

Exception in StringConcatFactory - Java 9


While learning java9 StringConcatFactory class I am unable to understand why following code with MethodHandles.publicLookup() throws StringConcatException exception while if MethodHandles.lookup() is used everything is working fine.

As per java docs of lookup:

"lookup - Represents a lookup context with the accessibility privileges of the caller"

StringConcatFactory.makeConcat(MethodHandles.publicLookup(),
"abc",MethodType.methodType(String.class));//Exception Here


StringConcatFactory.makeConcat(MethodHandles.lookup(), 
"abc", MethodType.methodType(String.class)); //Working fine

I am not sure where I am mistaken? Please help me understand this behavior.


Solution

  • The javadoc for makeConcat says about the first parameter:

    lookup Represents a lookup context with the accessibility privileges of the caller

    The lookup context returned by publicLookup does not have those privileges.

    Even if you concatenate nothing, the exception will still be thrown:

    MethodType concatType = MethodType.methodType(String.class); // No arguments, returns String
    StringConcatFactory.makeConcat(MethodHandles.publicLookup(), "abc", concatType); // Exception
    

    Because the access privileges of the context are checked in StringConcatFactory#doStringConcat:

    if ((lookup.lookupModes() & MethodHandles.Lookup.PRIVATE) == 0) {
        throw new StringConcatException("Invalid caller: " +
                lookup.lookupClass().getName());
    }
    

    The context needs a private lookup mode, and a publicLookup does not have it:

    System.out.println((MethodHandles.publicLookup().lookupModes()
        & MethodHandles.Lookup.PRIVATE) != 0); // false
    System.out.println((MethodHandles.lookup().lookupModes()
        & MethodHandles.Lookup.PRIVATE) != 0); // true