Skip to content
Advertisement

Getting Picocli to work with Springboot application

I have to convert a large Spring boot application into a flexible CLI tool, where the requests sent by the Spring boot application (among other things) are determined by user input at the command line. I decided to use picocli to implement the command line functionality, however I can’t figure out how to even do something as simple as print some text to stdout if the user passes a given option flag, Spring boot just runs as it normally does. How am I supposed to write this so picocli can function alongside Spring boot (and eventually control all the Spring boot stuff)

Advertisement

Answer

As a follow-up to this I eventually got the code working by refactoring out the “controller methods” into 3 as follows:

|
|_ MainApp.java
|_ CmdRunner.java
|_ TheCommand.java

Where MainApp is the @SpringBootApplication which basically just does:

System.exit(SpringApplication.exit(new SpringApplication(MainApp.class).run(args)));

Kicking everything off.

CmdRunner is an @Component & simple implementation of the CommandLineRunner Interface provided by SpringBoot, the most important bit is below:

    @Autowired
    private TheCommand theCommand;

    @Override
    public void run(String... args) {
       new CommandLine(theCommand).execute(args);
    }

It executes the passed cli arguments (which were passed to it from MainApp.java) on a new picocli CommandLine object. Which brings us to the final class, TheCommand.java which is simultaneously a picocli @Command & Springboot @Controller implementing the Runnable interface. And essentially just contains all the logic and (ever-growing)functionality I needed to deliver.

The only downside of this implementation is that when a user runs it with the --help flag, the app still runs the spring boot stuff making it a little unresponsive in that particular scenario.

Advertisement