Bug in catchException()

Rémi Forax forax at univ-mlv.fr
Fri Sep 4 03:44:41 PDT 2009


Le 04/09/2009 10:57, Attila Szegedi a écrit :
> Hi folks,
>
> This small testcase fails in MethodHandles.catchException() on MLVM:
>
> import java.dyn.MethodHandle;
> import java.dyn.MethodHandles;
> import java.dyn.MethodType;
>
> public class TestCatchException
> {
>       public static void main(String[] args) throws Throwable
>       {
>           MethodHandle throwing = findStatic("throwing");
>           MethodHandle catching = findStatic("catching");
>           MethodHandles.catchException(throwing, MyException.class,
>                   MethodHandles.dropArguments(catching, 0,
>                           MyException.class));
>       }
>
>       private static class MyException extends RuntimeException
>       {
>       }
>
>       private static MethodHandle findStatic(String name)
>       {
>           return MethodHandles.publicLookup().findStatic(
>                   TestCatchException.class, name,
> MethodType.make(int.class,
>                           Object.class));
>       }
>
>
>       public static int throwing(Object o)
>       {
>           throw new MyException();
>       }
>
>       public static int catching(Object o)
>       {
>           return 0;
>       }
> }
>
> Notably, it fails with:
>
> Exception in thread "main" java.dyn.NoAccessException: cannot access:
> *.java.dyn.MethodHandle.invoke(TestCatchException
> $MyException,java.lang.Object)int
> 	at sun.dyn.MemberName.newNoAccessException(MemberName.java:421)
> 	at sun.dyn.MemberName.newNoAccessException(MemberName.java:412)
> 	at sun.dyn.MemberName$Factory.resolveOrFail(MemberName.java:517)
> 	at java.dyn.MethodHandles$Lookup.findVirtual(MethodHandles.java:267)
> 	at sun.dyn.Invokers.exactInvoker(Invokers.java:66)
> 	at java.dyn.MethodHandles.exactInvoker(MethodHandles.java:761)
> 	at sun.dyn.FromGeneric.computeUnboxingInvoker(FromGeneric.java:137)
> 	at sun.dyn.FromGeneric.makeInstance(FromGeneric.java:160)
> 	at sun.dyn.FromGeneric.make(FromGeneric.java:174)
> 	at sun.dyn.MethodHandleImpl.convertArguments(MethodHandleImpl.java:460)
> 	at sun.dyn.MethodHandleImpl.makeGuardWithCatch(MethodHandleImpl.java:
> 840)
> 	at java.dyn.MethodHandles.catchException(MethodHandles.java:1397)
> 	at TestCatchException.main(TestCatchException.java:12)
>
> However, if I replace "MyException" with an exception on the boot
> classpath, i.e. IllegalArgumentException, then catchException() will
> succeed. Any advice for a workaround?
>    

If your signature isn't variant (you know the number of arguments)
and have no primitive type in your signature
(or don't mind the overhead),  you can create a static method like that

static void catchException(MethodHandle target, Class<? extends 
Throwable> c,
                                              MethodHandle 
exceptionHandler, Object o) throws Throwable {
   try {
     target.<void>invoke(o);
   } catch(Throwable t) {
      if (c.isInstance(t))
        exceptionHandler.<void>invoke(o);
      else
        throw t;
   }
}

Create a mh with lookup.findVirtual() and bound (insertArguments) the 
target,
the exception class and the exception handler.

> Attila.
>    

Rémi


More information about the mlvm-dev mailing list