How to avoid catching OutOfMemoryError in java and how to resolve class java.lang.OutOfMemoryError cannot be cast to class java.lang.Exception issue

for (int i = 0; i <listOfProcesses.size(); i++) {
    try {
        Future<Boolean> futureResult = executorCompletionService.take();
        boolean status = futureResult.get();
    } catch (InterruptedException e) {
        logger.error(e.getMessage());
    } catch (ExecutionException e) {
        logger.error(e.getMessage());
        Exception ex = (Exception)e.getCause();
        if(ex instanceof UncategorizedJmsException) {
            logger.error(e.getMessage());
        } else if(ex instanceof ApplicationException) {
            logger.error(e.getMessage());
        }
    }
}

When executing certain tasks, I face OutOfMemory error. This exception is caught as ExecutionException and I get the below mentioned class cast exception.

Unexpected error occurred in scheduled task
java.lang.ClassCastException: class java.lang.OutOfMemoryError cannot be cast to class java.lang.Exception 
(java.lang.OutOfMemoryError and java.lang.Exception are in module java.base of loader 'bootstrap')

How do I make errors to not be cast as exception? To handle other springboot exceptions, I am in need to cast as exception through this way (Exception)e.getCause(). How do I overcome this class cast excception? Kindly help


You can't cast OutOfMemoryError into an Exception.

Check the OutOfMemoryError Doc, and you can see that it is not a child class of Exception but from Error.

And as the Error Doc, states:

An Error is a subclass of Throwable that indicates serious problems that a reasonable application should not try to catch. Most such errors are abnormal conditions.

So you should not try to catch OutOfMemoryError as you don't have much options available at that point to recover your application state. For sure however you CAN NOT cast a OutOfMemoryError into an Exception as this is not possible.


Errors are not Exceptions.

Assuming that you get the OutOfMemoryError when calling an external service, then you could check if there was an Error before casting the cause to an Exception

 catch (ExecutionException e) {
    if (e.getCause() instanceof Error) {
        logger.error("Caught Error");
    } else {
        Exception ex = (Exception)e.getCause();
        if(ex instanceof UncategorizedJmsException) {
            logger.error(e.getMessage());
        } else if(ex instanceof ApplicationException) {
            logger.error(e.getMessage());
        }
    }
}