Spring Boot
Eclipse IDE
Java Development
Application Shutdown
Shutdown Hook

Terminated Spring Boot App in Eclipse - Shutdown hook not called

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

It is common to see Spring Boot cleanup callbacks run in production but not when stopping an app from Eclipse. The root cause is usually termination mode: graceful JVM shutdown versus hard process kill. Spring lifecycle hooks only run when the JVM has a chance to close the application context cleanly.

Core Sections

How Spring Boot shutdown hooks actually run

Spring Boot registers a JVM shutdown hook when the application starts. On graceful stop, Spring closes the ApplicationContext, then invokes bean destruction callbacks.

Typical callbacks include:

  • '@PreDestroy methods,'
  • 'DisposableBean.destroy,'
  • custom destroy methods.
java
1import jakarta.annotation.PreDestroy;
2import org.springframework.stereotype.Component;
3
4@Component
5public class ResourceCleaner {
6
7    @PreDestroy
8    public void closeResources() {
9        System.out.println("ResourceCleaner called");
10    }
11}

If the process is killed abruptly, this sequence may never run.

Why Eclipse stop behavior can differ

Eclipse normally sends a terminate signal, but depending on launch mode, debugger state, or forced termination, the process may exit without full JVM shutdown sequence. That is why the same code may behave differently between:

  • stopping via Eclipse terminate button,
  • calling ctx.close() programmatically,
  • stopping process externally.

You should verify shutdown behavior with controlled stop paths, not only manual IDE clicks.

Add deterministic shutdown test path

A reliable way to validate cleanup logic is to close context explicitly in tests or dedicated diagnostics mode.

java
1import org.springframework.boot.SpringApplication;
2import org.springframework.context.ConfigurableApplicationContext;
3
4public class ShutdownProbe {
5    public static void main(String[] args) {
6        ConfigurableApplicationContext ctx = SpringApplication.run(ShutdownProbe.class, args);
7        ctx.close();
8    }
9}

If cleanup callbacks run here but not in Eclipse terminate flow, issue is stop mechanism, not callback wiring.

Configure graceful server shutdown for web apps

For HTTP workloads, graceful shutdown helps complete active requests before closing.

properties
server.shutdown=graceful
spring.lifecycle.timeout-per-shutdown-phase=20s

This does not force hooks to run on hard kill, but it improves behavior when shutdown is graceful.

Handle background threads and executors correctly

Cleanup hooks often depend on background components stopping in time. If thread pools ignore interruption or block indefinitely, shutdown phase may timeout.

Best practices:

  • use managed executors,
  • honor interruption in loops,
  • keep destroy logic short,
  • avoid network-heavy cleanup in shutdown hook.

Long blocking code in @PreDestroy can make shutdown appear incomplete.

Do not rely on shutdown hooks for critical durability

Shutdown callbacks are useful for cleanup, but they are not guaranteed under crashes, force kills, or host failures. Critical data should be persisted during normal processing.

Examples:

  • persist checkpoints periodically,
  • flush queues transactionally,
  • commit critical state before acking upstream work.

Treat shutdown as best-effort finalization, not your primary data integrity mechanism.

Improve observability for termination debugging

Add structured logs for lifecycle events:

  • app start,
  • shutdown initiated,
  • destroy callbacks entered and completed,
  • exit code and duration.

With this, you can distinguish graceful shutdown from abrupt process termination quickly.

Validate production-like stop path

If deployment runs in containers or process managers, test with same signal behavior used in real environments. IDE-only testing misses important lifecycle details.

For containerized apps, validate termination handling with orchestrator stop actions and configured grace periods.

Common Pitfalls

  • Assuming every IDE stop action triggers graceful JVM shutdown.
  • Running expensive I O in @PreDestroy and hitting shutdown timeouts.
  • Ignoring interruption handling in worker threads.
  • Using shutdown hook as only place for critical data persistence.
  • Testing lifecycle cleanup only in local IDE and not in production-like runtime.

Summary

  • Spring Boot shutdown callbacks run only when JVM shutdown is graceful.
  • Eclipse termination can bypass cleanup depending on how process is stopped.
  • Use explicit context-close tests to verify callback wiring deterministically.
  • Configure graceful shutdown and thread interruption handling for predictable stop behavior.
  • Keep critical durability outside shutdown hooks and instrument lifecycle events clearly.

Related reading
Course
Intermediate
27 lessons
14 hours
OOD Fundamentals

Master object-oriented design from first principles, SOLID, design patterns, and classic interview problems with hands-on coding.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.