DEV Community

Sadiul Hakim
Sadiul Hakim

Posted on

Spring Shell Tutorial

1️. What is Spring Shell?

Spring Shell is a framework from the Spring ecosystem that helps you build interactive command-line applications (CLI apps) in Java — similar to how you might use git, kubectl, or spring.

It provides:

  • An interactive command prompt (REPL-style)
  • Auto-completion, history, help commands
  • Command parsing and argument handling
  • Integration with the Spring ecosystem (DI, configuration, etc.)

Example of apps built with it:

  • Spring Boot CLI (spring init, spring run)
  • Custom DevOps tools
  • Database administration tools
  • Internal automation tools for teams

2️. When to use Spring Shell?

Use Spring Shell when you want:

✅ An interactive CLI tool where users type commands (not just one-off arguments).
✅ To reuse your existing Spring services/configurations (via DI).
✅ A structured and maintainable CLI with auto-completion and help built in.

Avoid it if:

  • You just need a simple script (use picocli or args4j instead).
  • You want a non-interactive CLI (i.e., java -jar app.jar --do-something).

3️. Comparison: Spring Shell vs Other Java CLI Libraries

Feature Spring Shell Picocli JCommander args4j
Interactive shell (REPL) ✅ Yes ❌ No ❌ No ❌ No
Spring Integration ✅ Full (Beans, DI) ⚠️ Limited ⚠️ Limited ⚠️ Limited
Command-line parsing ✅ Built-in ✅ Powerful ✅ Decent ✅ Basic
Auto-completion & Help ✅ Yes ⚠️ Optional ⚠️ Optional ⚠️ Limited
Ease of setup ⚙️ Medium 🟢 Easy 🟢 Easy 🟢 Easy
Ideal for Interactive tools One-shot CLI apps Simple tools Legacy/small projects

In short:

  • Use Spring Shell for interactive tools or admin consoles.
  • Use Picocli for one-shot command tools.

4️. Core Components of Spring Shell

Spring Shell provides a few key annotations and classes you should know:

Component Description
@ShellComponent Marks a class that holds CLI commands.
@ShellMethod Marks a method as a CLI command.
@ShellOption Defines command-line options/parameters.
Application class Starts the Spring Shell environment.
PromptProvider Customize the prompt text.
CommandRegistration Programmatic way to define commands.
CommandCatalog Organizes available commands.

5. Examples of Spring Shell

Let’s walk through 3 examples, each with code and comments.


Example 1 — Basic Hello Command

Step 1. Add dependency (Maven)

<dependency>
    <groupId>org.springframework.shell</groupId>
    <artifactId>spring-shell-starter</artifactId>
    <version>3.3.2</version>
</dependency>
Enter fullscreen mode Exit fullscreen mode

Step 2. Main Application

package com.example.shellapp;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class ShellAppApplication {
    public static void main(String[] args) {
        SpringApplication.run(ShellAppApplication.class, args);
    }
}
Enter fullscreen mode Exit fullscreen mode

Step 3. Command Class

package com.example.shellapp.commands;

import org.springframework.shell.standard.ShellComponent;
import org.springframework.shell.standard.ShellMethod;
import org.springframework.shell.standard.ShellOption;

@ShellComponent // marks this class as a container for shell commands
public class HelloCommand {

    @ShellMethod(key = "hello", value = "Prints a personalized greeting.")
    public String sayHello(@ShellOption(defaultValue = "World") String name) {
        return "👋 Hello, " + name + "!";
    }
}
Enter fullscreen mode Exit fullscreen mode

Step 4. Run the app

Run it like any Spring Boot app:

mvn spring-boot:run
Enter fullscreen mode Exit fullscreen mode

You’ll see:

shell:> hello
👋 Hello, World!

shell:> hello Hakim
👋 Hello, Hakim!
Enter fullscreen mode Exit fullscreen mode

You’ve created your first interactive CLI tool.


Example 2 — Multi-command CLI

package com.example.shellapp.commands;

import org.springframework.shell.standard.ShellComponent;
import org.springframework.shell.standard.ShellMethod;
import org.springframework.shell.standard.ShellOption;

@ShellComponent
public class CalculatorCommands {

    @ShellMethod(key = "add", value = "Add two numbers.")
    public int add(int a, int b) {
        return a + b;
    }

    @ShellMethod(key = "multiply", value = "Multiply two numbers.")
    public int multiply(int a, int b) {
        return a * b;
    }

    @ShellMethod(key = "repeat", value = "Repeat a string n times.")
    public String repeat(
            @ShellOption String text,
            @ShellOption(defaultValue = "2") int times) {
        return text.repeat(times);
    }
}
Enter fullscreen mode Exit fullscreen mode

Now test:

shell:> add 5 10
15
shell:> multiply 4 3
12
shell:> repeat "Hi!" 3
Hi!Hi!Hi!
Enter fullscreen mode Exit fullscreen mode

Example 3 — Custom Prompt

You can customize the shell prompt by defining a PromptProvider bean.

package com.example.shellapp.config;

import org.jline.utils.AttributedString;
import org.jline.utils.AttributedStyle;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.shell.jline.PromptProvider;

@Configuration
public class PromptConfig {

    @Bean
    public PromptProvider customPromptProvider() {
        return () -> new AttributedString("SpringBaseShell:> ",
                AttributedStyle.DEFAULT.foreground(AttributedStyle.GREEN));
    }
}
Enter fullscreen mode Exit fullscreen mode

Now your shell prompt changes to:

SpringBaseShell:>
Enter fullscreen mode Exit fullscreen mode

Example 4 — Injecting Services (Spring DI)

You can use your regular Spring beans inside commands:

package com.example.shellapp.commands;

import com.example.shellapp.service.CalculatorService;
import org.springframework.shell.standard.ShellComponent;
import org.springframework.shell.standard.ShellMethod;

@ShellComponent
public class ServiceBasedCommands {

    private final CalculatorService calculatorService;

    public ServiceBasedCommands(CalculatorService calculatorService) {
        this.calculatorService = calculatorService;
    }

    @ShellMethod(key = "safeAdd", value = "Adds two numbers safely using service.")
    public int safeAdd(int a, int b) {
        return calculatorService.add(a, b);
    }
}
Enter fullscreen mode Exit fullscreen mode
package com.example.shellapp.service;

import org.springframework.stereotype.Service;

@Service
public class CalculatorService {
    public int add(int a, int b) {
        return a + b;
    }
}
Enter fullscreen mode Exit fullscreen mode

This shows full Spring DI in action


Summary

Concept Explanation
Framework Interactive CLI for Spring-based apps
Best for Admin consoles, developer tools, system management
Main Annotations @ShellComponent, @ShellMethod, @ShellOption
Advanced Features Custom prompt, DI, programmatic commands, completion
Alternative Use picocli for non-interactive single-command CLIs

Top comments (0)