-
Bug
-
Resolution: Done
-
Major
-
None
-
None
Runtime exceptions thrown within contextual proxies created via jakarta.enterprise.concurrent.ContextService are not propagated directly but are wrapped in an UndeclaredThrowableException. Here are the actions to reproduce this behaviour: 1) build the attached project by executing mvn package 2) deploy the reproducer.war 3) send a get request to
http://localhost:8080/reproducer/api/test
4) if the unexpected behaviour occurs you will see the message "unexpected: java.lang.reflect.UndeclaredThrowableException"
Intial findings:-
POSSIBLE ROOT CAUSE
The Reflection Wrapper: The ContextService uses Java Reflection (method.invoke()) to run code. By design, Java Reflection catches any exception thrown by the underlying method and wraps it inside a Checked Exception called InvocationTargetException.
The Failure to Unwrap: The EAP 8 proxy implementation catches this InvocationTargetException but fails to "peel it off" (unwrap it) to retrieve your original MyRuntimeException. It throws the wrapper exception instead.
The Interface Violation: interface MyProxy declares throws MyRuntimeException, but it does not declare throws InvocationTargetException.
The Final Crash: The Java Dynamic Proxy mechanism sees a Checked Exception (InvocationTargetException) being thrown that is not listed in the interface's throws clause. To adhere to Java rules, it creates an UndeclaredThrowableException to wrap this "illegal" exception and throws that to calling code.
@GET
public String test() {
try
catch (MyRuntimeException ex) {
// This catches it if it comes out clean
return "first expected: " + ex;
} catch (UndeclaredThrowableException ex) {
// 1. Get the immediate cause (likely InvocationTargetException)
Throwable cause = ex.getUndeclaredThrowable();
// 2. If the cause is a Reflection wrapper, peel it one more time
if (cause instanceof InvocationTargetException)
// 3. Now check if the inner-most cause is YOUR exception
if (cause instanceof MyRuntimeException) {
return "expected (unwrapped): " + cause;
}
// If it's something else entirely, rethrow or handle as unexpected
return "unexpected inner cause: " + cause;
} catch (Exception ex) {
return "unexpected: " + ex;
}
}
- clones
-
JBEAP-32050 [GSS](8.1.z) WFLY-21469 - Contextual proxy wraps runtime exceptions with UndeclaredThrowableException
-
- New
-