When running a Spring Shell application through the IDE and stopping the programm through the process kill button, then in almost all cases, the exit signal causes an exception:
java.lang.IllegalStateException: Terminal has been closed
at org.jline.terminal.impl.AbstractTerminal.checkClosed(AbstractTerminal.java:143)
at org.jline.terminal.impl.DumbTerminal.setAttributes(DumbTerminal.java:206)
at org.jline.reader.impl.LineReaderImpl.readLine(LineReaderImpl.java:810)
at org.jline.reader.impl.LineReaderImpl.readLine(LineReaderImpl.java:535)
at org.springframework.shell.jline.JLineInputProvider.readInput(JLineInputProvider.java:28)
at org.springframework.shell.core.InteractiveShellRunner.doRun(InteractiveShellRunner.java:94)
at org.springframework.shell.core.InteractiveShellRunner.run(InteractiveShellRunner.java:83)
at org.springframework.data.release.cli.ShellConfiguration.lambda$springShellApplicationRunner$1(ShellConfiguration.java:148)
at org.springframework.boot.SpringApplication.lambda$callRunner$0(SpringApplication.java:788)
at org.springframework.util.function.ThrowingConsumer$1.acceptWithException(ThrowingConsumer.java:82)
at org.springframework.util.function.ThrowingConsumer.accept(ThrowingConsumer.java:60)
at org.springframework.util.function.ThrowingConsumer$1.accept(ThrowingConsumer.java:86)
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:800)
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:788)
at org.springframework.boot.SpringApplication.lambda$callRunners$0(SpringApplication.java:776)
at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:184)
at java.base/java.util.stream.SortedOps$SizedRefSortingSink.end(SortedOps.java:357)
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:557)
at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:546)
at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:151)
at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:174)
at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:265)
at java.base/java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:611)
at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:776)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:328)
at org.springframework.data.release.Application.main(Application.java:51)
The issue surfaces only sometimes and upon application exit, it seems not to cause any harm, however, it would be neat to suppress the exception logging for this particular case. There is also another instance from JLineShellRunner that we tried to handle in our config code.
Version: 4.0.3
Config:
@Configuration(proxyBeanMethods = false)
public class ShellConfiguration {
@Bean
static BeanPostProcessor shellPostProcessor() {
return new BeanPostProcessor() {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof InteractiveShellRunner runner) {
runner.setDebugMode(true);
}
return bean;
}
};
}
@Bean
@Primary
@ConditionalOnProperty(prefix = "spring.shell.interactive", name = "enabled", havingValue = "true",
matchIfMissing = true)
public ShellRunner myJlineShellRunner(JLineInputProvider inputProvider, AbstractTerminal terminal,
CommandParser commandParser, CommandRegistry commandRegistry, Environment environment) {
JLineShellRunner jLineShellRunner = new JLineShellRunner(inputProvider, commandParser, commandRegistry) {
// reduce mount of exceptions on close.
@Override
public void flush() {
try {
super.flush();
} catch (Exception e) {
try {
terminal.input();
} catch (IllegalStateException ex) {
if (ex.getMessage() != null && ex.getMessage().contains("closed")) {
stop();
}
}
}
}
};
Boolean debugMode = environment.getProperty("spring.shell.debug.enabled", Boolean.class, false);
jLineShellRunner.setDebugMode(debugMode);
return jLineShellRunner;
}
@Bean
@ConditionalOnProperty(prefix = "spring.shell.interactive", name = "enabled", havingValue = "true",
matchIfMissing = true)
ApplicationRunner springShellApplicationRunner(ObjectProvider<InfoProperties> infoProperties,
Environment environment, ObjectProvider<ShellRunner> shellRunner) {
ResourceBanner banner = new ReleaseCliBanner(infoProperties);
return args -> {
PrintStream out = System.out;
banner.printBanner(environment, getClass(), out);
out.flush();
ShellRunner r = shellRunner.getObject();
if (r != null) {
r.run(args.getSourceArgs());
}
};
}
}
When running a Spring Shell application through the IDE and stopping the programm through the process kill button, then in almost all cases, the exit signal causes an exception:
The issue surfaces only sometimes and upon application exit, it seems not to cause any harm, however, it would be neat to suppress the exception logging for this particular case. There is also another instance from
JLineShellRunnerthat we tried to handle in our config code.Version: 4.0.3
Config: