timbre timbre
timbre timbre

Reputation: 13985

Prevent exiting the loop on runtime exception in Java

I have a service, and I would like it to have the following behavior:

  1. If service receives InterruptedException, or JVM shuts down, it should try to stop gracefully
  2. If there's some "catastrophic" event, the service should just quit
  3. Any other exception should be logged, state should reset, and loop should keep running
  4. Loop should not quit under any other circumstance.

So here's a overly simplified version of what I came up with.

On class level:

private static volatile boolean keepRunning = true;

static {
    Runtime.getRuntime().addShutdownHook(new Thread() {
        @Override
        public void run() {
            keepRunning = false;
        }
    }); 
}

And then the loop:

while(keepRunning) {
    try {
        // Do something useful
        Thread.sleep(10000); // just an example of something that can cause InterruptedException 
    }
    catch(InterruptedException e) { 
        keepRunning = false;
    }
    catch(Exception e) { // catches all exceptions, but not any errors
        // log it
        // reset state
    }
}
if(!keepRunning) {
    // shut down gracefully
}

It seems satisfies all 4 conditions, but there are some problems and unclear parts:

  1. (problem) Catching Exception and not doing anything is against all good practices. But is it acceptable in this case, or there's a better solution?
  2. (question) Is not catching Error all I need to do to satisfy condition #2? Or are there other situations I should be aware of?
  3. (unclear) Usually it's recommended that the "shut down gracefully" code goes into finally section after exception, and I don't really like that I have to check it after loop (if(!keepRunning)). But it seems doesn't fit in finally in this case. Is there a better way to do that?
  4. (question) This code is written for Java 7. Would anything be changed/improved with Java 8?

I will appreciate either direct answers to my questions, or pointers to different patterns/solutions. Thanks in advance.

Upvotes: 1

Views: 1242

Answers (1)

Krasimir Stoev
Krasimir Stoev

Reputation: 1754

It is ok to catch the Exception in your case.

Not catching Error is a good practice if you run tests.

The finally block is what you should use to shut down gracefully and yes - the if statement in the finally block is needed and generally ok.

If an error occurs, your finally block will still execute so it is all good.

This code is ok for both Java 7 and Java 8

Upvotes: 2

Related Questions