JDK-8211065 : Private method check in linkResolver is incorrect
  • Type: Bug
  • Component: hotspot
  • Sub-Component: runtime
  • Affected Version: 12
  • Priority: P2
  • Status: Closed
  • Resolution: Fixed
  • Submitted: 2018-09-24
  • Updated: 2019-05-28
  • Resolved: 2018-10-10
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 11
Related Reports
Relates :  
As discussed in JDK-8210768 this assertion in linkResolver has two problems:

  // For private method invocation we should only find the method in the resolved class.
  // If that is not the case then we have a found a supertype method that we have nestmate
  // access to.
  if (resolved_method->is_private() && resolved_method->method_holder() != resolved_klass) {
    ResourceMark rm(THREAD);
    DEBUG_ONLY(bool is_nestmate = InstanceKlass::cast(link_info.current_klass())->has_nestmate_access_to(InstanceKlass::cast(resolved_klass), THREAD);)
    assert(is_nestmate, "was only expecting nestmates to get here!");

First the nestmate access check should be between the current class and the resolved_method->method_holder() not the resolved class.

Second, we are only assured to have found a nestmate if normal access checking is enabled.

But on further examination of this and a related test case the entire check regarding private methods is incorrect and needs to be removed as it violates the JVMS method resolution rules.
Fix Request This is a JVMS conformance issue with the code added as part of JEP-181 "Nest-based Access Control" in JDK 11. There is a method resolution check that will throw NoSuchMethodError in a particular circumstance, which violates the JVMS method resolution rules. The fix is to simply delete the check and so is extremely low risk. A new test is added and a test for the erroneous NoSuchMethodError is modified. The patch applies cleanly to jdk11u.

The code that was put in LinkResolver was intended to verify that for private methods the selected method and the resolved method are always the same. But the code is broken in two ways. First, because there is a terminology issue that I didn't understand. When talking about method resolution, I've been considering the "resolved class" to be the class in which the method was found i.e. if you have a call to C.m but resolution only locates SuperC.m then to me SuperC is the resolved class. But that's not the way LinkResolver et al define things: // Naming conventions: // // resolved_method the specified method (i.e., static receiver specified via constant pool index) // sel_method the selected method (selected via run-time lookup; e.g., based on dynamic receiver class) // resolved_klass the specified klass (i.e., specified via constant pool index) // recv_klass the receiver klass The "resolved class" is the class specified in the MethodRef! (which is what you get from LinkInfo.resolved_class.) So the check was checking the wrong class - hence the failure in the current test case where we actually resolve to SuperC.m and SuperC and C are of course different. Secondly, it was a misplaced check as this is only resolution, not selection - a check that the selected and resolved method are the same can only happen in the selection code! So the entire check needs to be deleted. Further a test case in the nestmates tests that expected to get a NoSuchMethodError due to this check, must now expect the super class private method to be invoked - as per the JVMS resolution rules.