For the latest stable version, please use Spring Shell 3.3.1! |
Getting Started
To see what Spring Shell has to offer, we can write a trivial hello world shell application that has a simple argument.
Spring Shell is based on Spring Boot 3.2.7 and Spring Framework 6.1.10 and thus requires JDK 17. |
Creating a Project
For the purpose of this tutorial, we create a simple Spring Boot application by
using start.spring.io where you can choose Spring Shell dependency.
This minimal application depends only on spring-boot-starter
and
spring-shell-starter
.
Spring Shell version on start.spring.io is usually latest release.
|
With maven you’re expected to have something like:
<properties>
<spring-shell.version>3.2.6</spring-shell.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.shell</groupId>
<artifactId>spring-shell-starter</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.shell</groupId>
<artifactId>spring-shell-dependencies</artifactId>
<version>${spring-shell.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
With gradle you’re expected to have something like:
dependencies {
implementation 'org.springframework.boot:spring-boot-starter'
implementation 'org.springframework.shell:spring-shell-starter'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
dependencyManagement {
imports {
mavenBom "org.springframework.shell:spring-shell-dependencies:3.2.6"
}
}
Given that Spring Shell starts the REPL (Read-Eval-Print-Loop) because this
dependency is present, you need to either skip tests when you build (-DskipTests )
throughout this tutorial or remove the sample integration test that was generated
by start.spring.io. If you do not remove it, the integration test creates
the Spring ApplicationContext and, depending on your build tool, stays stuck in
the eval loop or crashes with a NPE.
|
Once compiled it can be run either in interactive mode:
$ $JAVA_HOME/bin/java -jar demo-0.0.1-SNAPSHOT.jar
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v3.2.7)
2022-09-13T18:42:12.818+01:00 INFO 12644 --- [ main] com.example.demo.DemoApplication
: Starting DemoApplication using Java 17.0.4 on ...
2022-09-13T18:42:12.821+01:00 INFO 12644 --- [ main] com.example.demo.DemoApplication
: No active profile set, falling back to 1 default profile: "default"
2022-09-13T18:42:13.606+01:00 INFO 12644 --- [ main] com.example.demo.DemoApplication
: Started DemoApplication in 1.145 seconds (process running for 1.578)
shell:>help
AVAILABLE COMMANDS
Built-In Commands
help: Display help about available commands
stacktrace: Display the full stacktrace of the last error.
clear: Clear the shell screen.
quit, exit: Exit the shell.
history: Display or save the history of previously run commands
version: Show version info
script: Read and execute commands from a file.
Or in non-interactive mode:
$JAVA_HOME/bin/java -jar demo-0.0.1-SNAPSHOT.jar help
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v3.2.7)
2022-09-13T18:42:12.818+01:00 INFO 12644 --- [ main] com.example.demo.DemoApplication
: Starting DemoApplication using Java 17.0.4 on ...
2022-09-13T18:42:12.821+01:00 INFO 12644 --- [ main] com.example.demo.DemoApplication
: No active profile set, falling back to 1 default profile: "default"
2022-09-13T18:42:13.606+01:00 INFO 12644 --- [ main] com.example.demo.DemoApplication
: Started DemoApplication in 1.145 seconds (process running for 1.578)
AVAILABLE COMMANDS
Built-In Commands
help: Display help about available commands
stacktrace: Display the full stacktrace of the last error.
clear: Clear the shell screen.
quit, exit: Exit the shell.
history: Display or save the history of previously run commands
version: Show version info
script: Read and execute commands from a file.
Check out Logging making logging to work better with shell apps. |
Your First Command
Now we can add our first command. To do so, create a new class (named whatever you want) and
annotate it with @ShellComponent
which is a variation of @Component
that is used to restrict
the set of classes that are scanned for candidate commands.
Then we can create a helloWorld
method that takes String
as an argument and
returns it with "Hello world". Add @ShellMethod
and optionally change command name
using key
parameter. You can use @ShellOption
to define argument default value
if it’s not given when running a command.
import org.springframework.shell.standard.ShellComponent;
import org.springframework.shell.standard.ShellMethod;
import org.springframework.shell.standard.ShellOption;
@ShellComponent
public class MyCommands {
@ShellMethod(key = "hello-world")
public String helloWorld(
@ShellOption(defaultValue = "spring") String arg
) {
return "Hello world " + arg;
}
}
New hello-world command becomes visible to help:
My Commands
hello-world:
And you can run it:
shell:>hello-world
Hello world spring
shell:>hello-world --arg boot
Hello world boot
The rest of this document delves deeper into the whole Spring Shell programming model.