JDK-6531596 : Wrong exception from Method.invoke() call
  • Type: Bug
  • Status: Closed
  • Resolution: Fixed
  • Component: hotspot
  • Sub-Component: runtime
  • Priority: P3
  • Affected Version: 6
  • OS: generic
  • CPU: generic
  • Submit Date: 2007-03-06
  • Updated Date: 2017-05-16
  • Resolved Date: 2007-06-20
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 Availabitlity Release.

To download the current JDK release, click here.
JDK 6 JDK 7
6u4Fixed 7Fixed
Related Reports
Relates :  
Relates :  
Relates :  
Description
Consider the following interface and implementor classes:

public interface Intf {
   // public void method1(); 
}

import java.lang.reflect.Method;
import java.lang.reflect.InvocationTargetException;

public class SubClass implements Intf {
    public static void main(String[] args) {
        SubClass sc = new SubClass();
        Class paramClasses[] = new Class[]{};
        
        for (int i = 0; i < 20; i++) {
          try{
            System.out.println("Try: " + i);
            Method method1 = sc.getClass().getMethod("method1",paramClasses);
            method1.invoke(sc);
          } catch(NoSuchMethodException nme){
            nme.printStackTrace();
          } catch(AbstractMethodError ame){
            ame.printStackTrace();
          } catch (IllegalAccessException e) {
            e.printStackTrace();
          } catch (InvocationTargetException e) {
            e.printStackTrace();
          }
        }
    } 
}

Steps to reproduce the issue:

1) Compiled both the classes
2) Uncomment method1() in Intf.java
3) recompile only Intf.java 

We get incompatible class set. Now, run

java Subclass 

You get AbstractMethodError for the first 15 iterations and then get InvocationTargetException that wraps AbstractMethodError. Actually, AbstractMethodError is expected always -- because "method1()" is not implemented in "SubClass" and therefore the linkage should fail always. Throwing InvocationTargetException seem to suggest that the method was called and resulted in some exception being thrown.

Comments
EVALUATION Fix is to always throw InvocationTargetException wrapping AbstractMethodError. Adding temporary command-line flag -XX:ReflectionWrapResolutionErrors. Default is the new behavior, turn this off to get backward compatibility until you have the opportunity to modify the caller's source code to check for InvocationTargetException.
2007-04-19

SUGGESTED FIX Kenneth Russell suggests the following fix: Need to change is the exception type being caught and re-thrown in the MethodAccessor. See sun.reflect.MethodAccessorGenerator, emitInvoke(), around line 701, where it emits the Throwable class as the catch class for the InvocationTargetException rethrow handler. This should perhaps be changed to catch and rethrow only Exceptions.
2007-03-06