I am developing a restful webservices using java. I am handling all runtime and other possible exception scenarios to send meaningful response to client.
When something like out of memory occurs, how do i make sure client gets meaningful response from the server?
Am using CXF and ExceptionMapper.
In Spring, you can catch your exceptions and map them to meaningful HTTP status codes. Following code might work for you (maps YourException to HTTP 500):
#ControllerAdvice
public class ExceptionProcessor {
#ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR)
#ExceptionHandler({YourException.class})
public void serverError(HttpServletRequest req, Exception exception) {
// ...
// Print exception to server log
exception.printStackTrace();
}
}
It's not an exception; it's an error: java.lang.OutOfMemoryError
You can catch it as it descends from Throwable:
try {
// create lots of objects here and stash them somewhere
} catch (OutOfMemoryError E) {
// release some (all) of the above objects
}
However, unless you're doing some rather specific stuff (allocating tons of things within a specific code section, for example) you likely won't be able to catch it as you won't know where it's going to be thrown from.
If the root cause of your problem is a memory leak, then the chances are that catching and recovering from the OOM will not reclaim the leaked memory. You application will keep going for a bit then OOM again, and again, and again at ever reducing intervals.
There is probably at least one good time to catch an OutOfMemoryError, when you are specifically allocating something that might be way too big:
I'm using HandlerExceptionResolver for this:
public class MyHandlerExceptionResolver implements HandlerExceptionResolver {
#Override
#ExceptionHandler(value = Exception.class)
public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
Your error processing goes here
}
}
So every exception, goes in resolveException, and I write appropriate message (In my case JSON) to the response.
There is also a good article http://www.journaldev.com/2651/spring-mvc-exception-handling-exceptionhandler-controlleradvice-handlerexceptionresolver-json-response-example
The problem with OutOfMemoryError is that it may happen in any thread, including threads that do not run your REST services code. In a server context, it is considered a bad practice to catch any Error. You should let it bubble up the call stack to be handled by the server code.
Instead of catching it, it would be better to investigate why you run out of memory and fix the cause. It could be that your server simply doesn't have enough memory allocated, or that you have a memory leak somewhere. You need to analyze the problem, for instance by analyzing the resulting heap dump(s), and ensure that it doesn't happen anymore.
In a managed environemnt like a Java EE server, it is dangerous and generally fallacious to assume you can recover from OutOfMemeoryError by catching it. Most often, you can't even catch it because it happens in a thread you don't control.
Related
I have an Scheduler in spring boot that fulfils a specific business task every X minutes. It works fine until it suddenly stops and does not engage anymore. There is no exception in the logs or any other logs. I need to restart the program for the scheduler to work again.
Sometimes the task of the scheduler goes wrong, and I throw an exception. To be able to handle those exceptions specifically, I wrote a custom ErrorHandler in Spring for the scheduler that resolves a seperate task for logging purposes. It is linked correctly to the scheduler and processes the task.
This issue can come up when an unhandled exception gets thrown inside of an ErrorHandler. I am not sure about the specifics, however a Runtime Exception thrown by an ErrorHandler (or a method inside of it) that gets propagated outside of it basically kills the scheduled thread for that task. Furthermore NOTHING gets written to the logs (no Exception message, nada).
The "easiest" way to resolve this is by wrapping the entirety of the method in a try/catch block catching Exception - although depending on why you have that Error Handler that might be a bad idea. This does not solve the underlying issue at hand, but it keeps the thread alive and allows you to log the issue.
Example:
public class MyErrorHandler implements ErrorHandler {
#Override
public void handleError(Throwable t) {
try {
//handle intended exception (ex. write to database or logs)
} catch (Exception e) {
//handle exception that was thrown while trying to handle the intended exception.
}
}
I have a question about how to handle EJBExceptions in some special cases.
General situation
In our application an EJB (3.0) DataAccessObjects(DAO) are responsible for all database access, these are used in other parts of the application.
Exceptions in the database layer are expected, for instance because of Optimistic Locking or Database constraint violations. The exceptions often thrown outside of the DOA class, because they occur on commit of the automatic JTA transaction. The calling class then receives this exception wrapped in an EJBException.
In most cases ignoring or logging and rethrowing the EJBException is best, as our JMS will trigger automatic retries for MessageDrivenBeans. In two cases, we don't want the exception to be propaged, as they have unwanted side effects.
Handling in JSF
In our JSF website we use the following pattern to display user friendly messages:
#ManagedBean
#ViewScoped
public class MyDataController {
#EJB
private MyDataDao myDataDao ;
public void addData(){
FacesMessage msg;
try {
Data data = new Data();
// Data gets filled
myDataDao.addData(data);
msg = new FacesMessage(FacesMessage.SEVERITY_INFO, "Succes",
data.getName());
}
catch (EJBException e) {
LOGGER.warn("Failed to add data"newCompanyName, e);
if (ExceptionUtils.getRootCause(e) instanceof SQLIntegrityConstraintViolationException) {
msg = new FacesMessage(FacesMessage.SEVERITY_FATAL, "Failed",
data.getName());
}
else {
msg = new FacesMessage(FacesMessage.SEVERITY_FATAL,
"Failed to add data for unknown reason", data.getName());
}
}
}
}
Handling in Schedules tasks
In a related case, we call the database from a timed task (created using #Schedule). However this task is destroyed when (two consecutive?) exceptions occur while running it (at least in Weblogic). For us it is very important that this task keeps running even if exceptions during handling occur.
We have achieved this by catching and logging all EJBExceptions, as explained in this answer and in this answer. (Actually in our case we decided to catch all exceptions).
Problem
The above solutions mostly work as intended. However, we recently found that Errors are wrapped in an EJBException as well. For instance an OutOfMemoryError. In this case it caused the error to be swallowed, disabling the normal mechanism in Weblogic that would restart the application in case of an OutOfMemoryError.
Effectively this has downgraded Errors to Exceptions.
Question
The only solution I have is to check the recursively check the exception and its causes for instances of type Error, and if that is the case, rethrow the EJBException.
What is the correct way to handle the EJB exceptions in these situations?
I can't seem to find proper solution to this. I would want to handle and display different message to the user depending on what happened. I'm using Spring WS and calling marshalSendAndReceive. On the returning service method at the moment I would simply catch (WebServiceIOException e), problem is that this exception is thrown by both Connection refused (wrong credentials) and when query takes longer than specified by client side (timeout)? Is there any proper way of handling these two without providing one general message that "something went wrong".
The WebServiceTemplate does its hard work in the method doSendAndReceive, where there is try...catch block and comprehensive error-handling. One of them is triggerAfterCompletion(int interceptorIndex, MessageContext messageContext, Exception ex), which delegates to the injected ClientInterceptor.
So, you just need to implement properly afterCompletion(MessageContext messageContext, Exception ex) to throw the appropriate business exception.
One way is to implement ClientInterception class
Another way is just catching general Exception class on where you send a request to web serice:
try {
webServiceTemplate.marshalSendAndReceive(request);
} catch(Exception e){
log.error("your custom message");
}
I am writing a web application using Spring 3 framework. Consider a situation where I have N number of controllers. Each controller delegates the request to exposed services and gets the response and return to users.
I would like to know if there is a better to way catch unexpected runtime exceptions thrown out of the controller code. I do not want to write something like the following for each of my controller methods. Or is it the only way?
try {
//call the service
} catch(ServiceException serviceEx) {
//do process for know exception
} catch(Exception ex) {
//return generic error message.
}
I know that we can use Spring Exception resolver. But I do not want to show different error page when unexpected error happens. I want to show some generic error message on UI as part of my widget?
Edit:
I also don't want my users to see the exception stacktrace when trying to perform some operations.
Sundar
I think catching RuntimeExceptions is bad practice. Originally RuntimeExceptions where thought as inicators to programming errors (e.g. NullPointerException to indicate that a null check is missing). Whereas checked exceptions where meant to indicate errors that the program can recover from (e.g. FileNotFoundException).
The problem today is that many frameworks use RuntimeExceptions where checked exceptions should be used. Therefore it is difficult to differentiate between cases where a program can handle the exception and where a programming error (bug) is encountered.
This is my personal view of this things for enterprise development. I know that most people mandate for dropping checked exceptions and handle everything as unchecked exception (as in Scala).
In my opinion you should only catch exceptions in your code from which you can recover. All other exceptions (checked or unchecked) should be caught by one über exceptionhandler which will log the exception and show the user some generic error page (possibly with an id that you can use to find what the exception was).
For example, in struts2 you would that this like so:
<global-exception-mappings>
<exception-mapping exception="java.lang.Exception" result="unrecoverableException"/>
</global-exception-mappings>
I never use spring mvc but this article seems to give you the options for an über exceptionhandler:
http://doanduyhai.wordpress.com/2012/05/06/spring-mvc-part-v-exception-handling/
You can catch runtime unexpected exceptions using this approach.
try {
...
} catch ( Exception e ) {
throw new RuntimeException("msg",e);
}
I think RuntimeException is designed for situations like breach of contract or some unrecoverable fault. Most of the time, you should just let the container or some outer infrastructure to handle it for you. Or you have to write a lot of redundant code to deal with them and it's kind of against the design philosophy of Spring.
In your case, may be you can leverage some filter or interceptor to catch those unexpected RuntimeException if you really need to transfer them to some other generic messages.
First, I am throwing run time exceptions for all unrecoverable exceptions, this causes these exceptions to travel up to the container, where I currently use an error page (defined in web.xml). In this error page is a scriptlet that invokes the logger.
The issue I am having with this is that the exception is no longer on the stack at this invocation. I have access to it from a request scope variable ("javax.servlet.error.message"). This string is the stack trace. I need this stack trace for logging purposes obviously, and on different app servers "javax.error_message" can be turned off for security reasons.......
So my question is, how can best log runtime exceptions from within Java EE apps without wrapping everything in this:
try {} catch (Exception e) {logger.log(...)}
?
I want some way to invoke the logger from the container maybe... right before the container catches the exception for example.
I found a solution. By adding a response filter and wrapping chain.doFilter(req, resp) like so:
try {
chain.doFilter(req,resp);
} catch (Exception e) {
logger.error("", e);
throw new RuntimeException(e);
}
This works fine so far and isn't dependent on a particular framework or app server.
There is nothing I know of in Servlet API to accomplish this.
However, you can do this in Tomcat with an instance listener. You can install a listener in context.xml like this,
<InstanceListener>myapp.MyListener</InstanceListener>
Tomcat fires InstanceEvent.AFTER_SERVICE_EVENT event right after the container catches the exception and before it throws the exception again. You can invoke the logger right there.
Correct me if I'm wrong, but the 'exception' object is present as a variable.. called 'exception' in your 'error' jsp. You could always use this object to log retrieve the exception information and log in in the error jsp itself.
AOP (Aspect Oriented Programming) would be my first choice.
You define:
join point (a runtime exception is thrown).
advice (your code to log the exception).
point cuts (which parts of your applications are "listening" this aspect).
Take a look at http://www.aspectj.org/