JDK-8016839 : JSR292: AME instead of IAE when calling a method
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.lang.invoke
  • Affected Version: hs25,8
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2013-06-18
  • Updated: 2023-07-21
  • Resolved: 2013-11-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 8 Other
8 b119Fixed hs25Fixed
Related Reports
Relates :  
Relates :  
Description
Pseudo code: 
interface I { void m() default {} }

class C implements I {
  private void m() {}
}

I o = new C(); o.m();

Observed behavior:
invokeinterface: IAE
MH.invoke* / indy: NPE

For MH.invokeExact case bytecode (Test1_I_C_m.class) is the following:
         0: ldc           #19                 // MethodHandle invokeinterface I.m:()V
         2: new           #21                 // class C
         5: dup           
         6: invokespecial #22                 // Method C."<init>":()V
         9: astore_1      
        10: aload_1       
        11: invokevirtual #28                 // Method java/lang/invoke/MethodHandle.invokeExact:(LI;)V

NPE is thrown on bci=11 (MH.invokeExact).

Test case is attached. 

How to run:
  $ java Test
Comments
URL: http://hg.openjdk.java.net/jdk8/jdk8/hotspot/rev/9d15b81d5d1b User: amurillo Date: 2013-12-03 22:05:32 +0000
03-12-2013

URL: http://hg.openjdk.java.net/jdk8/jdk8/jdk/rev/e822676cd3cd User: lana Date: 2013-12-03 19:10:36 +0000
03-12-2013

Current bug category is core-libs and it is fixed.
26-11-2013

Robots will create subCR for hotspot fix.
26-11-2013

Note that it is not really fixed; our robots are overoptimistic and declared victory after the first push. Should I reopen it until both parts of the fix are pushed?
26-11-2013

URL: http://hg.openjdk.java.net/jdk8/tl/jdk/rev/e822676cd3cd User: kvn Date: 2013-11-26 23:13:50 +0000
26-11-2013

Be aware (regarding recent change of title) it is not strictly limited to JSR292 or invokedynamic; the test case included with the patch demonstrates the bug with a mere invokeinterface, and it does not even need default methods.
25-11-2013

Release team: Approved for fixing
25-11-2013

Except for a small part (this part) of 8027733 the two bugs are duplicates: BasicTest.testInterfaceNotImplemented INVOKE_WITH_ARGS: Test1_I_C_m : FAILED nsk.share.TestFailure: Caught exception as expected, but it's type is wrong: expected: java.lang.IncompatibleClassChangeError; actual: java.lang.ClassCastException. But because of that one small part, they are NOT duplicates. However, it is entirely possible that the non-duplicating part has also been fixed, because it looks somewhat like a duplicate of 8026735, where failure to account for interface default methods in class hierarchy analysis causes the wrong exception to be thrown from C1. 8026735 was "resolved" about 40 hours before 8027733 was created, so this is possible given the slightest delay in translating test failure into filed bug, or it could be a related cause or an incorrect fix. The webrev(s) for this bug: http://cr.openjdk.java.net/~drchase/8016839/webrev-hotspot.01/ http://cr.openjdk.java.net/~drchase/8016839/webrev-jdk.01/ A summary of the fix: Add a throwIllegalAccessError static helper method to sun.misc.Unsafe Expose that within hotspot. In the event that an entry in an itable cannot be filled because of accessibility concerns, instead of leaving the slot null (by convention, converts to AME) instead fill in the helper method. Any calls therefore land in the helper method, which throws IAE.
25-11-2013

Karen, is the fix for this bug the same as JDK-8027733 or different? If you have a webrev, it would be easier for reviewing and approving.
25-11-2013

There are three reasons why we really want this fix in for 8. 1. customers' ability to diagnose a problem - if they get an IllegalAccessError they will look differently for a solution in their code than if they get an AbstractMethodError - and that will generate fewer phone calls. 2. security - we really want to generate IllegalAccessError for attempts to access methods that should not be accessible 3. ensuring we have shaken out the rest of default methods with invoke modes - the noise of this error in our testing is complicating ensuring that we understand whether other failures are problems in the product or in the tests and slowing down our completion of this work
22-11-2013

Release team: Approved for deferral. Moving to 8-pool. Once the 8u20 target is set up please retarget this bug to that release.
12-11-2013

8-critical-request: JDK-8016839 while it may be a P3 bug should be deferred to JDK8u20 on the grounds that the bug is not a regression in JDK8, and it has been around since at least JDK6 possible earlier. The issue itself is a corner case only observed with method handles are applied to incompatible compiled classes. Currently the test case produces an AbstractMethodError and does not cause a crash in the JVM. The Compiler team feels that this bug should be deferred to JDK8u20 on the basis that this is NOT a regression and a proper fix would require significant testing and potentially cause even more regressions. By waiting until JDK8u20 to fix this we can create a proper fix along with substantial testing to fix what is really a long standing issue in the JVM. This will affect pass rate by 0.375% though. SQE is OK with the deferral.
11-11-2013

Target fix date of November 19th
22-10-2013

Where we stand on this bug: 1) It is no longer "NPE instead of IAE" -- the fix for 8025260 converted the "wrong" exception to AbstractMethodError, which is less wrong. 2) It is not just a methodhandles bug; the problem is long-standing, but was dodged because it took a somewhat unusual case to catch the code doing the "wrong thing" (see comments above or new attached test case). 3) The preferred fix (the one that is clean, and might generalize to other errors, and that is low risk to the existing code) is new and a little tricky. What is needed is a "bridge method to nowhere", meaning one that always throws an exception, but we don't realize that we need this until very late in the game and other methods have already been somewhat processed. In addition, the "bridge method code" that we might use as a model for this is new-ish, being retired, and not that trustworthy. So, there's a non-zero number of secret handshakes that have to be made to get this to work properly, and it's not clear how long it will take to get them all nailed down. It's possible that we could precompile a single one of these very early, but it's not clear that a single method would work properly for all combinations of input signatures on all possible platforms.
21-10-2013

This file checks several cases of deliberately faulty method invocation, both through a method handle, and directly by a bytecode. It could serve as a regression test for this bug. It also demonstrates that this is NOT just a jsr292 bug.
20-10-2013

This is not just a jsr292/lambda bug. Any invokeinterface, if you run a valid receiver object through it first, will throw the "wrong exception" AbsractMethodError if it is subsequently run with an invalid receiver through it instead of IllegalAccessError. I'll attach a file adapted from another regression test that both exhibits this bug, as well as the non-method-handle version of the bug.
20-10-2013

It seems that this has to be fixed by creating a booby-trapped method, because null signals "AbstractMethodError" instead. After the fix t0 8025260, the NPE has been converted to AME -- but it is still wrong. Any hints on where this might be accomplished in the code?
30-09-2013

Assigning this to you
26-09-2013

NPE instead of IAE is a poor title for a bug; would someone searching for duplicates thing to search under those terms? It should say "NullPointerException instead of IllegalAccessError"
23-09-2013

RULE vm/runtime/defmeth/scenarios/Basic_v49_none_invoke_noredefine ExitCode 97 RULE vm/runtime/defmeth/scenarios/Basic_v49_none_invoke_redefine ExitCode 97 RULE vm/runtime/defmeth/scenarios/Basic_v49_strict_invoke_noredefine ExitCode 97 RULE vm/runtime/defmeth/scenarios/Basic_v49_strict_invoke_redefine ExitCode 97 RULE vm/runtime/defmeth/scenarios/Basic_v49_sync_invoke_noredefine ExitCode 97 RULE vm/runtime/defmeth/scenarios/Basic_v49_sync_invoke_redefine ExitCode 97 RULE vm/runtime/defmeth/scenarios/Basic_v49_syncstrict_invoke_noredefine ExitCode 97 RULE vm/runtime/defmeth/scenarios/Basic_v49_syncstrict_invoke_redefine ExitCode 97 RULE vm/runtime/defmeth/scenarios/Basic_v50_none_invoke_noredefine ExitCode 97 RULE vm/runtime/defmeth/scenarios/Basic_v50_none_invoke_redefine ExitCode 97 RULE vm/runtime/defmeth/scenarios/Basic_v50_strict_invoke_noredefine ExitCode 97 RULE vm/runtime/defmeth/scenarios/Basic_v50_strict_invoke_redefine ExitCode 97 RULE vm/runtime/defmeth/scenarios/Basic_v50_sync_invoke_noredefine ExitCode 97 RULE vm/runtime/defmeth/scenarios/Basic_v50_sync_invoke_redefine ExitCode 97 RULE vm/runtime/defmeth/scenarios/Basic_v50_syncstrict_invoke_noredefine ExitCode 97 RULE vm/runtime/defmeth/scenarios/Basic_v50_syncstrict_invoke_redefine ExitCode 97 RULE vm/runtime/defmeth/scenarios/Basic_v51_none_invoke_noredefine ExitCode 97 RULE vm/runtime/defmeth/scenarios/Basic_v51_none_invoke_redefine ExitCode 97 RULE vm/runtime/defmeth/scenarios/Basic_v51_strict_invoke_noredefine ExitCode 97 RULE vm/runtime/defmeth/scenarios/Basic_v51_strict_invoke_redefine ExitCode 97 RULE vm/runtime/defmeth/scenarios/Basic_v51_sync_invoke_noredefine ExitCode 97 RULE vm/runtime/defmeth/scenarios/Basic_v51_sync_invoke_redefine ExitCode 97 RULE vm/runtime/defmeth/scenarios/Basic_v51_syncstrict_invoke_noredefine ExitCode 97 RULE vm/runtime/defmeth/scenarios/Basic_v51_syncstrict_invoke_redefine ExitCode 97 RULE vm/runtime/defmeth/scenarios/Basic_v52_none_invoke_noredefine ExitCode 97 RULE vm/runtime/defmeth/scenarios/Basic_v52_none_invoke_redefine ExitCode 97 RULE vm/runtime/defmeth/scenarios/Basic_v52_strict_invoke_noredefine ExitCode 97 RULE vm/runtime/defmeth/scenarios/Basic_v52_strict_invoke_redefine ExitCode 97 RULE vm/runtime/defmeth/scenarios/Basic_v52_sync_invoke_noredefine ExitCode 97 RULE vm/runtime/defmeth/scenarios/Basic_v52_sync_invoke_redefine ExitCode 97 RULE vm/runtime/defmeth/scenarios/Basic_v52_syncstrict_invoke_noredefine ExitCode 97 RULE vm/runtime/defmeth/scenarios/Basic_v52_syncstrict_invoke_redefine ExitCode 97 RULE vm/runtime/defmeth/scenarios/DefaultVsAbstract_v49_none_invoke_noredefine ExitCode 97 RULE vm/runtime/defmeth/scenarios/DefaultVsAbstract_v49_none_invoke_redefine ExitCode 97 RULE vm/runtime/defmeth/scenarios/DefaultVsAbstract_v49_strict_invoke_noredefine ExitCode 97 RULE vm/runtime/defmeth/scenarios/DefaultVsAbstract_v49_strict_invoke_redefine ExitCode 97 RULE vm/runtime/defmeth/scenarios/DefaultVsAbstract_v49_sync_invoke_noredefine ExitCode 97 RULE vm/runtime/defmeth/scenarios/DefaultVsAbstract_v49_sync_invoke_redefine ExitCode 97 RULE vm/runtime/defmeth/scenarios/DefaultVsAbstract_v49_syncstrict_invoke_noredefine ExitCode 97 RULE vm/runtime/defmeth/scenarios/DefaultVsAbstract_v49_syncstrict_invoke_redefine ExitCode 97 RULE vm/runtime/defmeth/scenarios/DefaultVsAbstract_v50_none_invoke_noredefine ExitCode 97 RULE vm/runtime/defmeth/scenarios/DefaultVsAbstract_v50_none_invoke_redefine ExitCode 97 RULE vm/runtime/defmeth/scenarios/DefaultVsAbstract_v50_strict_invoke_noredefine ExitCode 97 RULE vm/runtime/defmeth/scenarios/DefaultVsAbstract_v50_strict_invoke_redefine ExitCode 97 RULE vm/runtime/defmeth/scenarios/DefaultVsAbstract_v50_sync_invoke_noredefine ExitCode 97 RULE vm/runtime/defmeth/scenarios/DefaultVsAbstract_v50_sync_invoke_redefine ExitCode 97 RULE vm/runtime/defmeth/scenarios/DefaultVsAbstract_v50_syncstrict_invoke_noredefine ExitCode 97 RULE vm/runtime/defmeth/scenarios/DefaultVsAbstract_v50_syncstrict_invoke_redefine ExitCode 97 RULE vm/runtime/defmeth/scenarios/DefaultVsAbstract_v51_none_invoke_noredefine ExitCode 97 RULE vm/runtime/defmeth/scenarios/DefaultVsAbstract_v51_none_invoke_redefine ExitCode 97 RULE vm/runtime/defmeth/scenarios/DefaultVsAbstract_v51_strict_invoke_noredefine ExitCode 97 RULE vm/runtime/defmeth/scenarios/DefaultVsAbstract_v51_strict_invoke_redefine ExitCode 97 RULE vm/runtime/defmeth/scenarios/DefaultVsAbstract_v51_sync_invoke_noredefine ExitCode 97 RULE vm/runtime/defmeth/scenarios/DefaultVsAbstract_v51_sync_invoke_redefine ExitCode 97 RULE vm/runtime/defmeth/scenarios/DefaultVsAbstract_v51_syncstrict_invoke_noredefine ExitCode 97 RULE vm/runtime/defmeth/scenarios/DefaultVsAbstract_v51_syncstrict_invoke_redefine ExitCode 97 RULE vm/runtime/defmeth/scenarios/DefaultVsAbstract_v52_none_invoke_noredefine ExitCode 97 RULE vm/runtime/defmeth/scenarios/DefaultVsAbstract_v52_none_invoke_redefine ExitCode 97 RULE vm/runtime/defmeth/scenarios/DefaultVsAbstract_v52_strict_invoke_noredefine ExitCode 97 RULE vm/runtime/defmeth/scenarios/DefaultVsAbstract_v52_strict_invoke_redefine ExitCode 97 RULE vm/runtime/defmeth/scenarios/DefaultVsAbstract_v52_sync_invoke_noredefine ExitCode 97 RULE vm/runtime/defmeth/scenarios/DefaultVsAbstract_v52_sync_invoke_redefine ExitCode 97 RULE vm/runtime/defmeth/scenarios/DefaultVsAbstract_v52_syncstrict_invoke_noredefine ExitCode 97 RULE vm/runtime/defmeth/scenarios/DefaultVsAbstract_v52_syncstrict_invoke_redefine ExitCode 97
07-08-2013

Attached test case still fails with the suggested fix for JDK-7087658.
03-07-2013

Possible dup of JDK-7087658. Checking…
01-07-2013