JDK-8266269 : Lookup::accessClass fails with IAE when accessing an arrayClass with a protected inner class as component class
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.lang.invoke
  • Affected Version: 16
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2021-04-29
  • Updated: 2021-07-18
  • Resolved: 2021-06-26
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 17 JDK 18
17 b29Fixed 18Fixed
Related Reports
CSR :  
Relates :  
Relates :  
Relates :  
Description
MethodHandles$Lookup.accessClass does not follow its documentation:
https://docs.oracle.com/en/java/javase/16/docs/api/java.base/java/lang/invoke/MethodHandles.Lookup.html#accessClass(java.lang.Class)

Specifically, it throws an exception when accessing an Array Class with a protected inner class as component class when using lookup object with full capabilities
(ie. java.lang.IllegalAccessException: access violation: class [Lp.A$TEST;, from q.B (unnamed module @60215eee)  in the testcase provided)

The expected behavior is accessClass should allow the access and return the passed in class.

Testcase:

package p;

public class A {
    protected enum TEST { ONE }
}



package q;

import p.A;

import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;

public class B extends A {
    public static void main(String[] args) throws Throwable {
        TEST[] arr = new TEST[1];
        Class<?> arrClass = arr.getClass();

        //1) is TEST[] visible
        try {
            MethodHandles.Lookup l = MethodHandles.lookup();
            Class<?> accessClass = l.accessClass(arrClass);
            System.out.println("Passed! accessClass is: "
                               + accessClass.getName());
        } catch (Exception e) {
            System.out.println(e);
        }

        //2) Byte code behaviour with TEST[]
        meth(null);

        //3) MH lookup with TEST[]
        MethodHandle mh = MethodHandles.lookup().findStatic(B.class, "meth", MethodType.methodType(void.class, TEST[].class));
        mh.invoke(null);
    }

    public static void meth(TEST[] arr) {
        System.out.println("called method");
    }
}

Comments
Changeset: 6eb734a6 Author: Mandy Chung <mchung@openjdk.org> Date: 2021-06-26 18:27:28 +0000 URL: https://git.openjdk.java.net/jdk17/commit/6eb734a60fdd982c94dd152a803809f148bff582
26-06-2021

Lookup::accessClass can test if an array class is accessible. An array class is accessible if and only if the element type of the specified array class is accessible. It's a bug in the implementation that accessibility should be determined using the element type rather than the array type.
24-06-2021