How Jersey Behaves on Not Mapped Exceptions? - java

The Jersey documentation explains how to convert an Exception to a Response, but it fails in detailing what will happen if my code throws an Exception that isn't mapped or derived from WebApplicationException.
This link says:
If the thrown exception is not handled by a mapper, it is propagated and handled by the container (i.e., servlet) JAX-RS is running within.
But this only explains how JAX-RS 2.0 is supposed to behave in general terms and not how Jersey, which is the container in this case, is going to handle this Exception.
I know some people will just say Well, why don't you try it out and see what happens?... and the answer is: Because I like to know the documentation and I try to avoid empirical results, since they can be contaminated with coincidences and exceptional cases.
So, the question is:
How Jersey deals with not mapped Exceptions, like SQLException or IllegalArgumentException? Exceptions that are thrown by one of my Resources and not handled by my code.

Jersey is always deployed somewhere. Usually, it's a servlet container (in an application server or Tomcat for instance), but in Java SE only environment it can be for instance Grizzly or even JDK HTTP server. See documentation for deployment options.
What happens to exception uncaught (or thrown) by Jersey is up to this deployment environment. For instance, the servlet container usually catch the Exception, logs it and returns http status 500.

Related

How to handle classes that need web resources?

I'm making a project in Java where I have a class that on its initialization connects to an API to retrieve some info. Based on that info it then provides several methods to use and analyse it.
But what if the web request fails ? Or if I have some other issue. Every method will now fail because they don't have the info required
What I did is having a boolean named loadInfo, and also a public method didLoadInfo, so that the client knows the state of the object. I also add a reloadInfo method to try to reload all info, and every method throws an exception if they are called when the loadInfo variable is false. That exception is a checked exception.
Is there another better way to handle this situation ? The exception thrown by all the methods should be checked or unchecked ?
EDIT:
Is a good idea to maintain default values, but how would you let the client know that the info returned may not be up to date ? Maybe another boolean indicating the info state ?
I think in this kind of scenarios you should use REST, so that your java components will be running on web server independently.
If you UI is up and running(it could be on angular or react js or html) and have REST calls in place to call java REST API, also you can configure other API in same web project independent of REST classes and will be initialized as soon at web context is loaded( for example if you are using spring, as soon as application context is loaded).
Since you are calling other services to retrieve info, use Netflix Hysytix to handle failure gracefully with a fallback method. Obviously, you have many more options to fallback logic.
Check out the official Hystrix Library here.
If you have time, check out my article on LinkedIn.

Stop the deployment if any error in the servlet context listener [duplicate]

I have a ServletContextListener which performs some database management functions when my Java EE application starts. This runs in my application before JPA and other pieces of the application are started/loaded. If the database maintenance fails I am logging the errors. If the database maintenance fails the application will not function properly and I would like to halt the application.
How can I gracefully and correctly stop the application from ServletContextListener.contextInitialized?
Solution given by Viven below is close but not quite. When I throw a RuntimeException Glassfish is left in an inconsistent state where its admin console is not accessible but some process is still running and keeping port 3700 (IIOP?) open which then prevents a restart.
In your listener, catch any exceptions and use servlet context attributes to store flags or other useful information about the error. You should probably also log something to indicate that the app is non-functional.
At this point, your options may be dictated by the architecture of your app. If all requests are handled by a single controller/dispatcher servlet, it might make sense to have its init method check the context attributes and throw an UnavailableException. Just be aware that the exception only applies to the specific servlet throwing it. This makes the approach less manageable if your app contains many servlets or allows direct access to other resources.
Another option would be to create a filter that intercepts every request, checks the context attributes and then throws an exception. Other variations are certainly possible.
If your ServletContextListener throws an exception, the webapp won't load correctly and the application server may block all subsequent request (and respond with a 500 error).
It isn't exactly preventing the application to start, nor stopping the application, but it prevents any further usage of the app and could be useful in your case.
After proper verification in the spec, this behaviour isn't mandatory in the specification. The server may (not must) return 500 errors. This solution has to be used carefully, therefore.
See this Answer for a quote from the Servlet spec.

How to propagate CXF exceptions from server to client

I have a WSDL First Apache CXF web service that works as expected, except that the exceptions that I throw on the server side are not received as such on the client.
Instead on the client side I get an exception of type SOAPFaultException in which only the detailMessage contains the message from the original server side Exception, but I'd like to receive the exact exception type I threw on the server side, including the cause chain.
I expected this to work like this by default, but it certainly doesn't in my system. I have been checking the CXF documentation to find hints about how to achieve this, but so far I haven't found anything useful.
The SOAP reference does not support stacktrace. If you want that you will need to copy the stacktrace as the message returned by the SoapFault.
With CXF you can do it by add a Interceptor on the income interceptor chain. Please refer to this question to see how to create a interceptor.
You should put it on the POST_INVOKE Phase.

CDI - handling errors

I am migrating my Seam 2 powered application to CDI and one of the things that is critical for me to retain is the error handling. In Seam 2, I simply replaced the default exception handler with my own, but in CDI, I am guessing I'll have to use an Interceptor.
How would I set this up as using an Interceptor requires me to specify where it will intercept calls? I mostly want to accomplish auditing, so when an exception occurs, it is logged, then a notification (email, xmpp, sms, phone call) is sent out to administrators.
When an exception occurs, is there simply an event that I can listen for and act on?
Walter
Are you using JSF2? If yes, instead of writing an Interceptor, you could register an ExceptionHandlerFactory in your web.xml as described here. In a CustomExceptionHandler, you can catch all Exceptions and handle them programmatically.
I'm using this approach in my JEE6-CDI-app, find it quite okay.

UnsupportedEncodingException thrown when using Resin and Grails

I've encountered a strange problem in a Grails webapp running under Grails:
java.io.UnsupportedEncodingException is thrown quite frequently due to various unknown encoding strings (such as "ISO8859_10", "ISO-8859-10"), and the strange thing is that this is done entirely within the Resin and Grails code. That is - no custom code is involved when the exception is thrown.
I'm not sure if it is Grails or the servlet container's code that should handle the exception. But I'd assume that the exception should be handled somewhere and not bubble up all the way to stderr.
This is the exception in full:
java.io.UnsupportedEncodingException: ISO-8859-10
at com.caucho.vfs.i18n.JDKWriter$OutputStreamEncodingWriter.<init>(JDKWriter.java:112)
at com.caucho.vfs.i18n.JDKWriter.create(JDKWriter.java:79)
at com.caucho.vfs.Encoding.getWriteEncoding(Encoding.java:231)
at com.caucho.server.connection.ToByteResponseStream.setEncoding(ToByteResponseStream.java:137)
at com.caucho.server.connection.AbstractHttpResponse.setLocale(AbstractHttpResponse.java:1683)
at com.caucho.server.connection.HttpServletResponseImpl.setLocale(HttpServletResponseImpl.java: 115)
at javax.servlet.ServletResponseWrapper.setLocale(ServletResponseWrapper.java:139)
at javax.servlet.ServletResponseWrapper.setLocale(ServletResponseWrapper.java:139)
at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1035)
at org.codehaus.groovy.grails.web.servlet.GrailsDispatcherServlet.doDispatch(GrailsDispatcherServlet.java:290)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:716)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:647)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:552)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:114)
My questions:
Should the exception be handled? If so, is it the responsibility of the servlet container (Resin) or the web framework (Grails)?
How would you go about solving this? (I'd rather not having the exception log cluttered with exceptions that I can do nothing about.)
I don't know much about Grails, but maybe you could try to find out where this weird encoding comes from.
Do your requests send Accept-Charset headers?
Do things work better if you set the "file.encoding" system property to something meaningful like UTF-8 in your resin.conf?
You can also set up a localeResolver bean in your application context. The DispatcherServlet will use that to resolve the locale. I haven't tried it myself, but my suggestion is to use the org.springframework.web.servlet.i18n.FixedLocaleResolver. It will delegate to Locale.getDefault() if you don't have any set up.

Categories