Skip to content

Stop interactive shell runner on context close#1356

Open
czpilar wants to merge 2 commits into
spring-projects:mainfrom
czpilar:patches/1224-devtools
Open

Stop interactive shell runner on context close#1356
czpilar wants to merge 2 commits into
spring-projects:mainfrom
czpilar:patches/1224-devtools

Conversation

@czpilar
Copy link
Copy Markdown
Contributor

@czpilar czpilar commented May 19, 2026

Resolves #1224

@fmbenhassine
Copy link
Copy Markdown
Contributor

Thank you for the PR. I quickly tested the change, and it seems to fix the issue. However, the first run of any command still fails, but subsequent calls succeed. Here is the output I get with the sample here when I run it in IntelliJ IDEA:

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/

 :: Spring Boot ::                (v4.0.6)

22:56:24.208 [main] INFO  o.s.s.s.h.boot.DemoApplication - Starting DemoApplication using Java 17.0.17 with PID 86776 (/Users/mbh/projects/spring-shell/spring-shell-samples/spring-shell-sample-spring-boot/target/classes started by mbh in /Users/mbh/projects/spring-shell)
22:56:24.210 [main] INFO  o.s.s.s.h.boot.DemoApplication - No active profile set, falling back to 1 default profile: "default"
Context is active: org.springframework.context.annotation.AnnotationConfigApplicationContext@1cdc4c27, started on Mon May 25 22:56:24 CEST 2026
22:56:24.416 [main] INFO  o.h.validator.internal.util.Version - HV000001: Hibernate Validator 9.0.1.Final
22:56:24.949 [main] INFO  o.s.s.s.h.boot.DemoApplication - Started DemoApplication in 0.862 seconds (process running for 1.05)
shell:>Closing and restarting context

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/

 :: Spring Boot ::                (v4.0.6)

22:56:26.290 [Thread-0] INFO  o.s.boot.SpringApplication - Starting application using Java 17.0.17 with PID 86776 (started by mbh in /Users/mbh/projects/spring-shell)
22:56:26.290 [Thread-0] INFO  o.s.boot.SpringApplication - No active profile set, falling back to 1 default profile: "default"
22:56:26.416 [Thread-0] INFO  o.s.boot.SpringApplication - Started application in 0.141 seconds (process running for 2.518)
shell:>help
Command elp not found
AVAILABLE COMMANDS

Built-In Commands
	clear: Clear the terminal screen
	help: Show help about available commands
	history: Display or save the history of previously run commands
	quit, exit: Exit the shell
	script: Execute commands from a script file
	version: Show version info
Demo Application Commands
	hello: say hello

shell:>help
AVAILABLE COMMANDS

Built-In Commands
	clear: Clear the terminal screen
	help: Show help about available commands
	history: Display or save the history of previously run commands
	quit, exit: Exit the shell
	script: Execute commands from a script file
	version: Show version info
Demo Application Commands
	hello: say hello

shell:>

I am not sure if the sample mimics exactly how devtools work, so I will check with the devtools plugin itself and get back to you (I don't want to waste time trying to fix an issue that does not happen with devtools). Also, typing Enter two times before running the first command makes the execution of the first command succeed, so I guess there is a small issue with the initialisation of the buffer.

Resolves spring-projects#1224

Signed-off-by: David Pilar <david@czpilar.net>
@czpilar czpilar force-pushed the patches/1224-devtools branch from ed969b8 to eaaec1c Compare May 29, 2026 16:42
Signed-off-by: David Pilar <david@czpilar.net>
@czpilar
Copy link
Copy Markdown
Contributor Author

czpilar commented May 29, 2026

@fmbenhassine I can reproduce it too. The dropped first character is a leftover JLine reader thread.

With the dumb terminal (IDE/Gradle), JLine reads stdin on a background thread blocked in a native read on FileDescriptor.in. It can't be interrupted (the stream wrapper's close() doesn't close the underlying descriptor, and the thread isn't parked in wait()), so closing the terminal doesn't stop it. After the restart the new context opens a second reader on the same descriptor, and the stale one wins the race for the first byte and discards it (so help becomes elp; pressing Enter twice works because the first newline is the byte it steals).

Fix: create the terminal once per JVM and reuse it across context restarts, so there's only ever one reader of stdin (closed on JVM shutdown instead of on context close). The first command now works on the first try.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

DevTools AutoReload Support

2 participants