Search code examples
javaspringspring-bootmavenpicocli

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)


Solution

  • 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.