United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
JDK-6531596 : Wrong exception from Method.invoke() call

Details
Type:
Bug
Submit Date:
2007-03-06
Status:
Closed
Updated Date:
2012-10-08
Project Name:
JDK
Resolved Date:
2007-06-20
Component:
hotspot
OS:
generic
Sub-Component:
runtime
CPU:
generic
Priority:
P3
Resolution:
Fixed
Affected Versions:
6
Fixed Versions:
hs10 (b14)

Related Reports
Backport:
Backport:
Backport:
Relates:
Relates:
Relates:

Sub Tasks

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
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
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



Hardware and Software, Engineered to Work Together