Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring REST Service does not shutdown after an OutOfMemoryError

I am experiencing what I consider a strange behaviour for a Java application. I am using Spring Boot 1.4.1 to develop a REST Service. Due to a bug in my code, an invocation to the service results in an OutOfMemoryError.

Surprisingly, the service responds to the request that generates the error with the following message:

{
  "timestamp": 1487862480405,
  "status": 500,
  "error": "Internal Server Error",
  "exception": "java.lang.OutOfMemoryError",
  "message": "No message available",
  "path": "/entity/exportCsv"
}

So far so good. What is more surprisingly is that the REST service does not shutdown after experiencing the Error. Someone said that after an Error the best thing to do is to properly log it and shutdown everything. The presence of an error should mean that the system is in an unrecoverable state.

Why does Spring MVC adopt such a strange policy in case of Error? Is it possible to force the exit from the application (the REST service) after an Error happened?

If you want to reproduce the above use case, just use the following code.

@RestController
@RequestMapping("/entity")
class Controller {
    @RequestMapping(value = "/exportCsv", method = RequestMethod.GET)
    ResponseEntity exportCsv() {
        if (true)
            throw new OutOfMemoryError();
        return null;
    }
}

Thanks to all.

EDIT: if you do think that catching an Error is a normal way to develop Java applications, please, try to have a look to these references:

  • When to catch java.lang.Error?
  • Why Catching Throwable or Error is bad?
  • And many other...
like image 856
riccardo.cardin Avatar asked Feb 23 '17 16:02

riccardo.cardin


2 Answers

When running your application, you can specify the behavior of your application when an error like this happens with the following arguments:

  • -XX:+HeapDumpOnOutOfMemoryError : this will create a dump which can be analysed afterwards. The dump will be located at the location given at -XX:HeapDumpPath=some_path.
  • -XX:OnOutOfMemoryError=path_to_some_script.sh : this will run a script (it must be runnable by the same user which runs the application) when the application returns an error as an OutOfMemory
  • -XX:OnError=path_to_some_script.sh : same as before, but for more generic exceptions.

Reference: http://www.oracle.com/technetwork/java/javase/clopts-139448.html

like image 126
Sergio Lema Avatar answered Oct 23 '22 05:10

Sergio Lema


I would say that in the world of web apps this is not suprising at all.

Imagine a RestController as a web page. If it contains an error, the web server nor the application that generates the page is expected to stop working. This error is usually a local or temporary problem related to your request. In these situations the web server should instead respond with HTTP status 500.

Spring even has an built-in error handling feature that lets you to handle each specific error differently. See this article by Paul Chapman for more info.

UPDATE: Regarding your inquiry about the OOM error handling: I think you missed how memory management and object allocation in JVM works. See Understand the OutOfMemoryError Exception.

like image 33
stuchl4n3k Avatar answered Oct 23 '22 03:10

stuchl4n3k