(reflect) Accessing members of inner annotations types

Peter Levart peter.levart at gmail.com
Fri Jan 3 15:55:28 UTC 2014


On 01/03/2014 03:52 PM, Peter Levart wrote:
> This is would be all right until such proxy class 
> (com.sun.proxy.$Proxy1 in our example) has to access some 
> package-private types in some specific package. This happens in your 
> Named.List annotation  implementation class. It implements a member 
> method with the following signature:
>
> public Named[] value() {...
>
> ...where the return type is an array of a package-private type Named. 
> Public class in com.sun.proxy package can not access package-private 
> types in other packages! 

Investigating this further, I found that the declaration itself is not 
problematic. It's the code in the implemented proxy method that tries to 
access the package-private Named class. Here's how the bytecode looks 
like for such proxy method:


   public final pkg.Named[] value() throws ;
     Signature: ()[Lpkg/Named;
     flags: ACC_PUBLIC, ACC_FINAL
     Code:
       stack=10, locals=2, args_size=1
          0: aload_0
          1: getfield      #16                 // Field 
java/lang/reflect/Proxy.h:Ljava/lang/reflect/InvocationHandler;
          4: aload_0
          5: getstatic     #67                 // Field 
m3:Ljava/lang/reflect/Method;
          8: aconst_null
          9: invokeinterface #28,  4           // InterfaceMethod 
java/lang/reflect/InvocationHandler.invoke:(Ljava/lang/Object;Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;
*        14: checkcast     #69                 // class "[Lpkg/Named;"*
         17: areturn
         18: athrow
         19: astore_1
         20: new           #42                 // class 
java/lang/reflect/UndeclaredThrowableException
         23: dup
         24: aload_1
         25: invokespecial #45                 // Method 
java/lang/reflect/UndeclaredThrowableException."<init>":(Ljava/lang/Throwable;)V
         28: athrow
       Exception table:
          from    to  target type
              0    18    18   Class java/lang/Error
              0    18    18   Class java/lang/RuntimeException
              0    18    19   Class java/lang/Throwable


... I think the error is thrown at the "checkcast" bytecode. The 
improvement suggested still holds. If the proxy class was generated in 
the specific package, error would not be thrown. But the requirement to 
take into account all implemented interfaces and all types encountered 
in the interface method signatures to calculate the package of proxy 
class it too strict. Only implemented interfaces and return types of all 
interface methods need to be taken into consideration. Here's an example 
of bytecode that illustrates how method parameters are passed to 
InvocationHandler:


   public final void doWith(pkg.Named[]) throws ;
     Signature: ([Lpkg/Named;)V
     flags: ACC_PUBLIC, ACC_FINAL
     Code:
       stack=10, locals=3, args_size=2
          0: aload_0
          1: getfield      #16                 // Field 
java/lang/reflect/Proxy.h:Ljava/lang/reflect/InvocationHandler;
          4: aload_0
          5: getstatic     #57                 // Field 
m3:Ljava/lang/reflect/Method;
          8: iconst_1
          9: anewarray     #22                 // class java/lang/Object
         12: dup
         13: iconst_0
         14: aload_1
         15: aastore
         16: invokeinterface #28,  4           // InterfaceMethod 
java/lang/reflect/InvocationHandler.invoke:(Ljava/lang/Object;Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;
         21: pop
         22: return
         23: athrow
         24: astore_2
         25: new           #42                 // class 
java/lang/reflect/UndeclaredThrowableException
         28: dup
         29: aload_2
         30: invokespecial #45                 // Method 
java/lang/reflect/UndeclaredThrowableException."<init>":(Ljava/lang/Throwable;)V
         33: athrow
       Exception table:
          from    to  target type
              0    23    23   Class java/lang/Error
              0    23    23   Class java/lang/RuntimeException
              0    23    24   Class java/lang/Throwable


... as can be seen, no parameter types are referenced in order to wrap 
the parameters with Object[] array.

Regards, Peter




More information about the core-libs-dev mailing list