eclipse-ee4j / eclipse-ee4j/jersey

Exception thrown in resource constructor is not mapped using ExceptionMapper (results in 500 error instead)

Open
#4,436 7 comments 1 reaction 0 assignees View on GitHub
enhancement
Dominant language
Java
Stars
730
Forks
382
PR merge metrics
No merged PRs in 30d

Description

When upgrading from 1.19 to 2.30.1, I hit this bug (which I later [found on StackOverflow](https://stackoverflow.com/questions/49053353/jersey-exception-mapper-not-handling-exceptions-in-resource-constructor) as well).

`Exception` thrown in resource constructor is not mapped using `ExceptionMapper`. Instead I get:
```
Exception

javax.servlet.ServletException: A MultiException has 2 exceptions. They are:
1. java.lang.RuntimeException
2. java.lang.IllegalStateException: Unable to perform operation: create on jersey.test.MyResource

org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:410)
org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:346)
org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:366)
org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:319)
org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:205)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)

Root Cause

A MultiException has 2 exceptions. They are:
1. java.lang.RuntimeException
2. java.lang.IllegalStateException: Unable to perform operation: create on jersey.test.MyResource

org.jvnet.hk2.internal.ClazzCreator.create(ClazzCreator.java:368)
org.jvnet.hk2.internal.SystemDescriptor.create(SystemDescriptor.java:463)
org.glassfish.jersey.inject.hk2.RequestContext.findOrCreate(RequestContext.java:59)
org.jvnet.hk2.internal.Utilities.createService(Utilities.java:2102)
org.jvnet.hk2.internal.ServiceLocatorImpl.internalGetService(ServiceLocatorImpl.java:758)
org.jvnet.hk2.internal.ServiceLocatorImpl.internalGetService(ServiceLocatorImpl.java:721)
org.jvnet.hk2.internal.ServiceLocatorImpl.getService(ServiceLocatorImpl.java:691)
org.glassfish.jersey.inject.hk2.AbstractHk2InjectionManager.getInstance(AbstractHk2InjectionManager.java:160)
org.glassfish.jersey.inject.hk2.ImmediateHk2InjectionManager.getInstance(ImmediateHk2InjectionManager.java:30)
org.glassfish.jersey.internal.inject.Injections.getOrCreate(Injections.java:105)
org.glassfish.jersey.server.model.MethodHandler$ClassBasedMethodHandler.getInstance(MethodHandler.java:260)
org.glassfish.jersey.server.internal.routing.PushMethodHandlerRouter.apply(PushMethodHandlerRouter.java:51)
org.glassfish.jersey.server.internal.routing.RoutingStage._apply(RoutingStage.java:86)
org.glassfish.jersey.server.internal.routing.RoutingStage._apply(RoutingStage.java:89)
org.glassfish.jersey.server.internal.routing.RoutingStage._apply(RoutingStage.java:89)
org.glassfish.jersey.server.internal.routing.RoutingStage._apply(RoutingStage.java:89)
org.glassfish.jersey.server.internal.routing.RoutingStage.apply(RoutingStage.java:69)
org.glassfish.jersey.server.internal.routing.RoutingStage.apply(RoutingStage.java:38)
org.glassfish.jersey.process.internal.Stages.process(Stages.java:173)
org.glassfish.jersey.server.ServerRuntime$1.run(ServerRuntime.java:245)
org.glassfish.jersey.internal.Errors$1.call(Errors.java:248)
org.glassfish.jersey.internal.Errors$1.call(Errors.java:244)
org.glassfish.jersey.internal.Errors.process(Errors.java:292)
org.glassfish.jersey.internal.Errors.process(Errors.java:274)
org.glassfish.jersey.internal.Errors.process(Errors.java:244)
org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:265)
org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:232)
org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:680)
org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:394)
org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:346)
org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:366)
org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:319)
org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:205)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)

Root Cause

java.lang.RuntimeException
jersey.test.MyResource.(MyResource.java:11)
sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
java.lang.reflect.Constructor.newInstance(Constructor.java:423)
org.glassfish.hk2.utilities.reflection.ReflectionHelper.makeMe(ReflectionHelper.java:1356)
org.jvnet.hk2.internal.ClazzCreator.createMe(ClazzCreator.java:248)
org.jvnet.hk2.internal.ClazzCreator.create(ClazzCreator.java:342)
org.jvnet.hk2.internal.SystemDescriptor.create(SystemDescriptor.java:463)
org.glassfish.jersey.inject.hk2.RequestContext.findOrCreate(RequestContext.java:59)
org.jvnet.hk2.internal.Utilities.createService(Utilities.java:2102)
org.jvnet.hk2.internal.ServiceLocatorImpl.internalGetService(ServiceLocatorImpl.java:758)
org.jvnet.hk2.internal.ServiceLocatorImpl.internalGetService(ServiceLocatorImpl.java:721)
org.jvnet.hk2.internal.ServiceLocatorImpl.getService(ServiceLocatorImpl.java:691)
org.glassfish.jersey.inject.hk2.AbstractHk2InjectionManager.getInstance(AbstractHk2InjectionManager.java:160)
org.glassfish.jersey.inject.hk2.ImmediateHk2InjectionManager.getInstance(ImmediateHk2InjectionManager.java:30)
org.glassfish.jersey.internal.inject.Injections.getOrCreate(Injections.java:105)
org.glassfish.jersey.server.model.MethodHandler$ClassBasedMethodHandler.getInstance(MethodHandler.java:260)
org.glassfish.jersey.server.internal.routing.PushMethodHandlerRouter.apply(PushMethodHandlerRouter.java:51)
org.glassfish.jersey.server.internal.routing.RoutingStage._apply(RoutingStage.java:86)
org.glassfish.jersey.server.internal.routing.RoutingStage._apply(RoutingStage.java:89)
org.glassfish.jersey.server.internal.routing.RoutingStage._apply(RoutingStage.java:89)
org.glassfish.jersey.server.internal.routing.RoutingStage._apply(RoutingStage.java:89)
org.glassfish.jersey.server.internal.routing.RoutingStage.apply(RoutingStage.java:69)
org.glassfish.jersey.server.internal.routing.RoutingStage.apply(RoutingStage.java:38)
org.glassfish.jersey.process.internal.Stages.process(Stages.java:173)
org.glassfish.jersey.server.ServerRuntime$1.run(ServerRuntime.java:245)
org.glassfish.jersey.internal.Errors$1.call(Errors.java:248)
org.glassfish.jersey.internal.Errors$1.call(Errors.java:244)
org.glassfish.jersey.internal.Errors.process(Errors.java:292)
org.glassfish.jersey.internal.Errors.process(Errors.java:274)
org.glassfish.jersey.internal.Errors.process(Errors.java:244)
org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:265)
org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:232)
org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:680)
org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:394)
org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:346)
org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:366)
org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:319)
org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:205)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)

```
The same `Exception` thrown in the resource's `@GET` method is mapped as expected.

I also know this worked as expected in 1.19, so wonder why the behavior changed.

Can be reproduced using this code (more or less copy-pasted from SO):
https://github.com/namedgraph/jersey-exception-mapper-test/tree/master/src/main/java/jersey/test/constructor_exception
Includes `ConstructorExceptionTest` which fails.

Run and go to http://localhost:8080/jersey-test/test/MyResource
* `throw new RuntimeException()` in `MyResource()` constructor will result in 500 error (shown above)
* `throw new RuntimeException()` in `MyResource.get()` will show `Mapped` returned by `ExceptionResponseMapper`

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.