Skip to content

Declaring an ApplicationRunner causes Spring Shell application to close immediately #1330

@3ric-T

Description

@3ric-T

Description

A Spring Boot application using Spring Shell version 4.0.1 with interactive mode configured exits immediately after start if classes implementing ApplicationRunner are present and declared as @Component


Versions affected

  • Spring Shell 4.0.1
  • Spring Boot 4.0.5

Operating System

  • Linux (Ubuntu 24.04.4)
  • Java 25.0.2 (OpenJDK)

Steps to Reproduce

  1. Generate a minimal project from start.spring.io with Spring Shell as the only dependency
  2. Add a Component that implement ApplicationRunner :
package com.example.demo.runner;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;

@Component
public class DemoRunner implements ApplicationRunner {
    private static final Logger LOGGER = LoggerFactory.getLogger(DemoRunner.class);

    @Override
    public void run(ApplicationArguments args) throws Exception {
        LOGGER.info("This is my runner!");
    }
}
  1. Build the application:
./gradlew build
  1. Launch the application:
java -jar demo-0.0.1-SNAPSHOT.jar

Expected Behavior

The application should:

  1. Complete startup
  2. Display the Spring Shell prompt
  3. Wait for user input in interactive mode
  4. Remain running until the user exits

Actual Behavior

The application:

  1. Completes startup successfully
  2. Immediately triggers the shutdown hook
  3. Exits with code 0 without entering interactive mode

Additional Context

  • The problem did not occur with Spring Shell 3.4.x
  • Enabling spring.shell.context.close=true did not solve anything

Minimal Reproducer

A minimal project demonstrating the problem is available here:
👉 https://github.com/3ric-T/spring-shell-reproducer

Possible Workaround

When possible, the ApplicationRunner implementations can be replaced by classes with methods annotated with @EventListener

Logs


Negative matches:
-----------------
(...)
   ShellRunnerAutoConfiguration#nonInteractiveShellRunner:
      Did not match:
         - @ConditionalOnProperty (spring.shell.interactive.enabled=false) found different value in property 'enabled' (OnPropertyCondition)

   ShellRunnerAutoConfiguration#springShellApplicationRunner:
      Did not match:
         - @ConditionalOnMissingBean (types: org.springframework.boot.ApplicationRunner; SearchStrategy: all) found beans of type 'org.springframework.boot.ApplicationRunner' demoRunner (OnBeanCondition)
(...)

Unconditional classes:
----------------------
(...)
    org.springframework.shell.core.autoconfigure.ShellRunnerAutoConfiguration
(...)

2026-04-02 11:38:25.084  INFO 2882 --- [           main] com.example.demo.DemoApplication         : Started DemoApplication in 1.063 seconds (process running for 1.413)
2026-04-02 11:38:25.086 DEBUG 2882 --- [           main] o.s.b.a.ApplicationAvailabilityBean      : Application availability state LivenessState changed to CORRECT
2026-04-02 11:38:25.089  INFO 2882 --- [           main] com.example.demo.runner.DemoRunner       : This is my runner!
2026-04-02 11:38:25.090 DEBUG 2882 --- [           main] o.s.b.a.ApplicationAvailabilityBean      : Application availability state ReadinessState changed to ACCEPTING_TRAFFIC
2026-04-02 11:38:25.095 DEBUG 2882 --- [ionShutdownHook] s.c.a.AnnotationConfigApplicationContext : Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@5b1f29fa, started on Thu Apr 02 11:38:24 CEST 2026
2026-04-02 11:38:25.097 DEBUG 2882 --- [ionShutdownHook] o.s.c.support.DefaultLifecycleProcessor  : Stopping beans in phase 1073741823
2026-04-02 11:38:25.098 DEBUG 2882 --- [ionShutdownHook] o.s.c.support.DefaultLifecycleProcessor  : Bean 'applicationTaskExecutor' completed its stop procedure
2026-04-02 11:38:25.098 DEBUG 2882 --- [ionShutdownHook] o.s.c.support.DefaultLifecycleProcessor  : Stopping beans in phase -2147483647
2026-04-02 11:38:25.098 DEBUG 2882 --- [ionShutdownHook] o.s.c.support.DefaultLifecycleProcessor  : Bean 'springBootLoggingLifecycle' completed its stop procedure
2026-04-02 11:38:25.098 DEBUG 2882 --- [ionShutdownHook] o.s.s.concurrent.ThreadPoolTaskExecutor  : Shutting down ExecutorService 'applicationTaskExecutor' 

Would you like to contribute a fix?

  • Yes
  • No

I'm unfortunately not very familiar with how Spring Boot internally works but I'm keen to learn


Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions