Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Executing a single command and exiting from Spring Shell 2

I stumbled upon this question from a while back, explaining how to get a Spring Shell application to exit after calling it from the command line with a single command. However, testing this in 2.0.0 with Spring Boot, it does not seem to be the case any more that invoking the JAR with command arguments will execute that command and then exit. The shell just starts as normal without executing the supplied command. Is it still possible to do this? If not, would it be possible to pass the arguments from the JAR execution to Spring Shell and then trigger an exit after execution?

For example, let's say I have a command, import that has a couple options. It could be run in the shell like this:

$ java -jar my-app.jar

> import -f /path/to/file.txt --overwrite
Successfully imported 'file.txt'

> exit

But it would be nice to be able to simply execute and exit, for the sake of building a script that can utilize this function:

$ java -jar my-app.jar import -f /path/to/file.txt --overwrite
Successfully imported 'file.txt'
like image 838
woemler Avatar asked Sep 22 '17 14:09

woemler


People also ask

How do you run a spring shell?

Running the Shell from the Jar File After obtaining the JAR file we run it using the command java -jar our-spring-shell-jar-name. jar . This will open our shell in the command line and have it ready for us to type in commands.

Can we run Spring Boot from command line?

The Spring Boot CLI is a command line tool that you can use if you want to quickly develop a Spring application. It lets you run Groovy scripts, which means that you have a familiar Java-like syntax without so much boilerplate code. You can also bootstrap a new project or write your own command for it.

What is spring command?

Spring Boot CLI(Command Line Interface) is a Spring Boot software to run and test Spring Boot applications from command prompt. When we run Spring Boot applications using CLI, then it internally uses Spring Boot Starter and Spring Boot AutoConfigurate components to resolve all dependencies and execute the application.


2 Answers

Run it with @my-script, like so:

java -jar my-app.jar @my-script

Where my-script is a file with your commands:

import -f /path/to/file.txt --overwrite
like image 87
Greg St.Onge Avatar answered Sep 20 '22 08:09

Greg St.Onge


Just to add, I found another way of doing this, doesn't give you the option to run in interactive mode but using your profiles above you can of course swap the configuration. Please note I'm using lombok and jool (just in case anyone copy pastes and gets funny issues!)

Entry

@SpringBootApplication
public class Righter {

    public static void main(String[] args) {
        SpringApplication.run(Righter.class, args);
    }

    @Bean
    public ApplicationRunner shellRunner(Shell shell) {
        return new NonInteractiveShellRunner(shell);
    }

Application runner:

@Order(0)
public class NonInteractiveShellRunner implements ApplicationRunner{

    private final Shell shell;

    public NonInteractiveShellRunner(Shell shell) {
        this.shell = shell;
    }

    @Override
    public void run(ApplicationArguments args) throws Exception {
        shell.run(new CommandInputProvider(args.getSourceArgs()));
    }

    public static class PredefinedInputProvider implements InputProvider{

        private final Input input;
        private boolean commandExecuted = false;

        public PredefinedInputProvider(String[] args) {
            this.input = new PredefinedInput(args);
        }

        @Override
        public Input readInput() {
            if (!commandExecuted){
                commandExecuted=true;
                return input;
            }
            return new PredefinedInput(new String[]{"exit"});
        }

        @AllArgsConstructor
        private static class PredefinedInput implements Input{

            private final String[] args;

            @Override
            public String rawText() {
                return Seq.of(args).toString(" ");
            }

            @Override
            public List<String> words(){
                return Arrays.asList(args);
            }
        }

    }

}
like image 28
Alex Avatar answered Sep 19 '22 08:09

Alex