0

I'm trying to keep my application alive in order to listen for some messages from my queue. However, once my application receives a SIGTERM, I would like to ensure that my application shutdown nicely. Meaning, ensure that the jobs, internally, has finished first, before the shutdown.

After reading about it , I came up with this:

@Component
public class ParserListenerStarter {

    public static void main(final String[] args) throws InterruptedException {
        ConfigurableApplicationContext context = new AnnotationConfigApplicationContext(ParserReceiveJmsContext.class);
        context.registerShutdownHook();
        System.out.println("Listening...");
        Runtime.getRuntime().addShutdownHook( //
                new Thread() {
                    @Override
                    public void run() {
                        System.out.println("Closing parser listener gracefully!");
                        context.close();
                    }
                });

        while (true) {
            Thread.sleep(1000);
        }
    }

}

Then I send a kill command to my application; and this is my output:

Listening...
// output from my other beans here
Closing parser listener gracefully!

Process finished with exit code 143 (interrupted by signal 15: SIGTERM)

The shutdown methods from my beans were not called:

@PreDestroy public void shutdown() {..}

I'm not an expert in Spring, so I'm sorry for any silly point that I'm missing here.

How can I shutdown my beans and then close my application nicely ?

Valter Silva
  • 16,446
  • 52
  • 137
  • 218

1 Answers1

5

All you need:

context.registerShutdownHook();

So, add the code above and then your @PreDestroy method will be invoked. After that you don't need to do anything else. It means you must can delete

 Runtime.getRuntime().addShutdownHook( //
            new Thread() {
                @Override
                public void run() {
                    System.out.println("Closing parser listener gracefully!");
                    context.close();
                }
            });

EDIT: Documentation says that you can have multiple shutdown hooks:

When the virtual machine begins its shutdown sequence it will start all registered shutdown hooks

So the statement below is incorrect:

When you added this, you replaced the Spring hook, which do the beans destroying, because internally, method looks like

if (this.shutdownHook == null) {
        // No shutdown hook registered yet.
        this.shutdownHook = new Thread() {
            @Override
            public void run() {
                doClose();
            }
        };
        Runtime.getRuntime().addShutdownHook(this.shutdownHook);
    }
Kirill Gamazkov
  • 3,277
  • 1
  • 18
  • 22
Mykola Yashchenko
  • 5,103
  • 3
  • 39
  • 48