71

I have the following code

public Object handlePermission(ProceedingJoinPoint joinPoint, RequirePermission permission) throws AccessException, Throwable {
    System.out.println("Permission = " + permission.value());
    if (user.hasPermission(permission.value())) {
        System.out.println("Permission granted ");
        return joinPoint.proceed();
    } else {
        System.out.println("No Permission");
        throw new AccessException("Current user does not have required permission");
    }

}

When I use a user that does not have permissions, I get java.lang.reflect.UndeclaredThrowableException instead of AccessException.

user373201
  • 10,945
  • 34
  • 112
  • 168
  • [When Does Java Throw UndeclaredThrowableException? | Baeldung](https://www.baeldung.com/java-undeclaredthrowableexception) – Jason Law Aug 31 '21 at 08:33

1 Answers1

109

AccessException is a checked exception, but it was thrown from the method that doesn't declare it in its throws clause (actually - from the aspect intercepting that method). It's an abnormal condition in Java, so your exception is wrapped with UndeclaredThrowableException, which is unchecked.

To get your exception as is, you can either declare it in the throws clause of the method being intercepted by your aspect, or use another unchecked exception (i.e. a subclass of RuntimeException) instead of AccessException.

axtavt
  • 239,438
  • 41
  • 511
  • 482
  • 5
    +1. I would only add that in these situations `UndeclaredThrowableException` wraps the original exception; `getCause()` will return `AccessException`. – Tomasz Nurkiewicz Mar 30 '11 at 18:39
  • 4
    I had declared AccessException in the method that intercepts. Changing AccessException to extend RuntimeException worked. – user373201 Mar 30 '11 at 18:40
  • 9
    If you're the author of the code that is being caught with `UndeclaredThrowableException` it might be good to read [this post that has some details](http://amitstechblog.wordpress.com/2011/07/24/java-proxies-and-undeclaredthrowableexception/) – EdgeCaseBerg Jan 29 '14 at 21:45
  • @EdgeCaseBerg and anyone else, I think I was caught out by the proxy issue but then used throw new `ValidationException('delete.failure',s.errors)` - this then returned correct message instead of `UndeclaredThrowableException` which is what `RuntimeException` was returning – V H Dec 16 '16 at 11:36
  • In my case declaring `throws ClassNotFoundException` in the method didn't work but wrapping the exception inside a `RuntimeException` did help (`throw new RuntimeException(e)`). For some context: I was using it inside a gradle `@TaskAction` annotated method – futchas Dec 14 '17 at 16:27
  • This link is equally important https://stackoverflow.com/questions/3715298/dynamic-proxy-and-checked-exceptions – ASharma7 May 29 '19 at 07:28