Hi,
I have an application using Jersey which serves both HTML based on templates (MvcFeature+Mustache) and standard REST JSON.
When enabling the MvcFeature the ErrorTemplateExceptionMapper is also enabled. However, ErrorTemplateExceptionMapper maps all Exceptions which are not mapped by a more specific Exception mapper. This is fine for the resources returning templates. However, it interferes with the resources returning JSON.
The ErrorTemplateExceptionMapper causes an illegal state exception hiding the and preventing the propagation of the information about the cause of the original exception. As an example I get this very uninformative output:
sep. 15, 2015 8:41:53 AM org.glassfish.jersey.server.ServerRuntime$Responder process
SEVERE: Error occurred when processing a response created from an already mapped exception.
sep. 15, 2015 8:41:53 AM org.glassfish.jersey.server.ServerRuntime$Responder release
WARNING: Attempt to release request processing resources has failed for a request.
java.lang.IllegalStateException: Illegal attempt to call getOutputStream() after getWriter() has already been called.
at org.glassfish.grizzly.http.server.Response.getNIOOutputStream(Response.java:624)
at org.glassfish.grizzly.http.server.Response.getOutputStream(Response.java:649)
at org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpContainer$ResponseWriter.writeResponseStatusAndHeaders(GrizzlyHttpContainer.java:270)
at org.glassfish.jersey.server.ServerRuntime$Responder$1.getOutputStream(ServerRuntime.java:611)
at org.glassfish.jersey.message.internal.CommittingOutputStream.commitStream(CommittingOutputStream.java:200)
at org.glassfish.jersey.message.internal.CommittingOutputStream.flushBuffer(CommittingOutputStream.java:305)
at org.glassfish.jersey.message.internal.CommittingOutputStream.commit(CommittingOutputStream.java:261)
at org.glassfish.jersey.message.internal.CommittingOutputStream.close(CommittingOutputStream.java:276)
at org.glassfish.jersey.message.internal.OutboundMessageContext.close(OutboundMessageContext.java:846)
at org.glassfish.jersey.server.ContainerResponse.close(ContainerResponse.java:412)
at org.glassfish.jersey.server.ServerRuntime$Responder.release(ServerRuntime.java:717)
at org.glassfish.jersey.server.ServerRuntime$Responder.process(ServerRuntime.java:445)
at org.glassfish.jersey.server.ServerRuntime$1.run(ServerRuntime.java:277)
at org.glassfish.jersey.internal.Errors$1.call(Errors.java:271)
at org.glassfish.jersey.internal.Errors$1.call(Errors.java:267)
at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
at org.glassfish.jersey.internal.Errors.process(Errors.java:267)
at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:297)
at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:254)
at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:1030)
at org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpContainer.service(GrizzlyHttpContainer.java:378)
at org.glassfish.grizzly.http.server.HttpHandler$1.run(HttpHandler.java:219)
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:565)
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:545)
at java.lang.Thread.run(Thread.java:745)
I would prefer to have my own exception mapper handle exceptions raised in the JSON resources.
public class ExceptionMapper implements ExceptionMapper<Exception>
However, I don’t see how they can co-exists as both get the same distance in the org.glassfish.jersey.internal.ExceptionMapperFactory.find(Class<T>, T) method. I don’t see any way to disambiguate.
Are there any way to only enable an ExceptionMapper for a particular resource?
There does not seem to be a method to remove an exception mapper from the resource configuration.
Is it possible to override the ErrorTemplateExceptionMapper?
Any suggestions?
Thanks.
—
Janus Friis Nielsen
Senior Software Architect, GWAPT, CSM, PhD.
E jfn_at_sepior.com