Graceful handling of exception thrown while creating beans - spring

I want my Spring MVC web app to gracefully handle a particular type of exception thrown while creating the beans.
The construction of one of my beans reads configuration data from an external file. If that configuration data is faulty, one of my bean constructors will throw an exception of a particular type. As the cause of the problem would be a faulty configuration file, I want my web application to respond with a useful log message and/or an error page, rather than a stack-trace of the thrown exception. So I guess I need some kind of exception handler hooked into the IOC container or dispatcher servlet. How can I do that?
Just to be clear. I'm asking about exceptions thrown as the servlet is initialising, not as it handles HTTP requests, so #ExceptionHandler annotations on controllers are not useful.

I worked around this difficulty by introducing a level of indirection. My bean is really just a handle. If the configuration file is bad, the bean catches the exception, logs a message, and notes that reading failed. Accessing the bean later then throws a suitable exception.

Related

Does Spring have any way of catching/handling ServletException?

I there any predefined way in Spring to catch or handle ServletException?
I mean any annotation or class that catches them and provide utility methods for them?
There are several techniques and approaches to handle Servlet Exceptions with Spring.
I can redirect you to this interesting link:
Exception Handling for REST with Spring
Exceptions can be managed at the DispatchServlet level, Controller level or application level. You can chose the method that better fit your needs.
Exception handling can be implemented per controller (using the old #ExceptionHandler or more recent and easy to use ResponseStatusException), or within global exception handler that centralize all exception management (using #ControllerAdvice)

Correct way to find if spring context was started

In my spring bean I want to use send spring event functionality. The problem is event can't be sent if spring context was not initialized and my bean by some reasons can send events before that happen.
I used the following:
implement ApplicationContextAware and use ConfigurableApplicationContext.isActive() - this becomes true in the beginning of the context initialization phase
use ConfigurableApplicationContext.isRunning() - this throws exception IllegalStateException("LifecycleProcessor not initialized...
listen for ContextRefreshedEvent - this doesn't work because this is inner bean and is used as a property for the bean that implements BeanFactoryPostProcessor
implementing SmartLifecycle also doesn't work because for inner beans
So what is the EASY and correct way to determine if context is running and event can be sent?
Hopefully this is already fixed SPR-13667 in spring 4.1.7.

Can I handle BeanCreationException in spring?

Spring will throw BeanCreationException if there's some problem when creating a bean. If there's a way to do some thing when this exception is thrown, say, halt the process?

What is "persistence exception translation" for #Repository beans

I was reading Spring with annotation part and I came across #Repositoryannotation
I read that #Repository beans differ from #Component beans in the sense that they are eligible for persistence exception translation.
Can somebody please elaborate what is meant by persistence exception translation?
Persistence Exception Translation is the process of converting low level persistence exceptions into high level Spring exceptions.
From the SpringSource Site:
Common data access exceptions. Spring can wrap exceptions from your
O/R mapping tool of choice, converting them from proprietary
(potentially checked) exceptions to a common runtime
DataAccessException hierarchy. This allows you to handle most
persistence exceptions, which are non-recoverable, only in the
appropriate layers, without annoying boilerplate catches/throws, and
exception declarations. You can still trap and handle exceptions
anywhere you need to. Remember that JDBC exceptions (including DB
specific dialects) are also converted to the same hierarchy, meaning
that you can perform some operations with JDBC within a consistent
programming model.
One of the major benefits of this is that exceptions are turned into Runtime Exceptions, in effect you are not required to add the throws declaration to your methods signature.
http://static.springsource.org/spring/docs/2.5.x/reference/orm.html
It provides a consistent exception hierarchy regardless of the database type or persistence methodology/technology you're using.
You get the same exceptions for the same types of errors regardless of whether you're using Oracle vs MySQL or JPA vs JDBC.
Take a look at the SQLErrorCodeSQLExceptionTranslator and sql-error-codes.xml.
sql-error-codes.xml is particularly interesting as you can see all the various vendor-specific error codes and what exception in the hierarchy they map to.
The Spring exception translation mechanism can be applied transparently to all beans annotated with #Repository – by defining an exception translation bean post processor bean in the Context

How to ignore Exceptions during Spring context initialization?

How to configure Spring to continue load its beans, if one of its defined beans in its init method throwed exception. lazy-init="true" option doesn't help - it is just ignored. In this bean init() method i try to open connection with server, which may fail to load the application spring context. Spring 3.0.6
The Idea of Exceptions is to fix the cause of them, not to ignore them.
Have that said: I have never seen anything for that: you have to do it by our own. Put a try catch around the init method that consume the exception and log it.
If you have real AspectJ, then you can use it for that task too. But Spring-AOP will not work.
(comment) I use side library where I should call init method, which establish connection with some server, where problem might appear.
In this case. what about a factory that provides the bean which causes the trouble to the context. The factory should check the connection first (or wait for the exception) (what exactly you do is an implementation detail) and return the bean if every thing is correct. If the connection is failing, then the factory return a Dummy implementation instead..

Resources