1

This isn't about how to handle exceptions in Spring MVC or anything. I specifically need to handle an exception that can happen while spring is starting, i.e. before the whole application context is even initialised.

For a bit of background, the application in question is an IoT node that allows remote access to electronic equipment. It has a little h2 database built in to persist some data. That data is nice to have at some moments, but not really essential for the application to work.

It so happens that the device the application is running on can get its power cut every once in a while, and if that happens while there was a write operation to the database going on, the file is corrupt and a JdbcSQLException will be thrown when the application tries to boot again. Since the data is not really essential, the easiest way to make the application work again is to just delete the database and let h2 recreate it. But in order to do that, I have to catch the exception so I can react to it. The application does not have to continue starting, it will be booted up again by systemd. I really just need to identify the exception and delete the file, that's it.

There is one obvious way to do it, which is to put SpringApplication.run in a try-catch block. But it's also really ugly, because I get the exception I'm looking for nested inside a gazillion spring exceptions that were caused by h2 failing to start.

It was also suggested that I catch the exception in the bean that instantiates the database, but unfortunately there is no bean instantiating it. The DB serves as a Quartz job-store and as such is fully managed by spring. Its entire presence in the code are the following entries in the properties file:

spring.quartz.job-store-type=jdbc
spring.quartz.properties.org.quartz.jobStore.misfireThreshold=900000
spring.datasource.name=h2
spring.datasource.url=jdbc:h2:file:${config.folder}controller
spring.datasource.driverClassName=org.h2.Driver

My question is, is there a way to register some kind of exception handler, or other means, to handle the exception directly when it happens, when I can identify it much more easily?

UncleBob
  • 907
  • 1
  • 9
  • 28

1 Answers1

1

Depends how you've declared the bean. What's wrong with simply wrapping the bean like this?

@Configuration
class Conf {
    @Bean
    public DB foo() throws JdbcSQLException
    {
        try
        {
            return new DB();
        }
        catch(JdbcSQLException e)
        {
            deleteDatabase();
            throw JdbcSQLException;
        }
    }

    public static void deleteDatabase()
    {
        //...
    }
}
Michael
  • 34,340
  • 9
  • 58
  • 100
  • 2 reasons: One, I suck at spring-boot and didn't even consider this, and unfortunately two, the whole DB serves as a Quartz Job-store and is set up by spring itself. There's no bean instantiating it in the code. I'm not really sure what I'd have to do to instantiate it myself... (see reason one). – UncleBob Sep 13 '18 at 13:21
  • 1
    How does spring instantiate it? There must be some dependency that you include, or some properties that you define, or something. Please edit your question with those details. – Michael Sep 13 '18 at 13:28
  • 1
    @UncleBob Thanks. Given that info, I think you must be using a starter. Something like `spring-boot-starter-jdbc` or `spring-boot-starter-data-jpa`. Do you have anything like that? – Michael Sep 13 '18 at 14:27
  • Indeed I do, there's spring-boot-starter-quartz and spring-boot-starter-jdbc in the dependencies. – UncleBob Sep 13 '18 at 14:30
  • 1
    Cool. You basically need to do this to override the autoconfiguration: https://stackoverflow.com/questions/28821521/configure-datasource-programmatically-in-spring-boot – Michael Sep 13 '18 at 14:47
  • Thanks. It took me a bit to get around to this again. I've looked at your link and implemented it, only to find out that the exception is not thrown when the DataSource is instantiated, but later on when it is initialised. In other words, putting the instantiation into a try-catch block doesn't solve my problem as I assumed it would. Still thanks a lot for the help! – UncleBob Sep 17 '18 at 11:31