Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to run spring boot application both as a web application as well as a command line application?

Currently, I am trying to use the CommandLineRunner along with the ConfigurableApplicationContext to run a spring boot application both as a web application by default and as a standalone command line application on demand (via command line parameters of some sort). I am struggling figuring out how to solely run this as a console application when program arguments are supplied. Please any suggestions would help.

  • Main class - SpringApplication
  • CommandLineRunner
like image 303
Brandon Beschta Avatar asked Aug 10 '17 13:08

Brandon Beschta


2 Answers

I had the same requirement. This is how I was able to achieve it:

@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        SpringApplicationBuilder app = new SpringApplicationBuilder(Application.class);
        if (args.length == 0) { // This can be any condition you want
            app.web(WebApplicationType.SERVLET);
        } else {
            app.web(WebApplicationType.NONE);
        }
        app.run(args);
    }
}

And this is a console application runner.

@Component
@ConditionalOnNotWebApplication
public class ConsoleApplication implements CommandLineRunner {
    @Override
    public void run(String... args) {
        System.out.println("************************** CONSOLE APP *********************************");
    }
}

When you build your bootJar, you can run application as Web app using java -jar app.jar and as a command line app using java -jar app.jar anything #based on the condition you specified.

Hope this helps.

EDIT:

A better way to achieve this is changing Application.java as following and keeping ConsoleApplication.java as shown above.

@SpringBootApplication
public class Application {

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

and then running your bootJar with java -jar -Dspring.main.web-application-type=NONE app.jar will run the application as console application. And not passing any spring.main.web-application-type will run as a web application.

like image 108
Garbage Avatar answered Nov 15 '22 17:11

Garbage


The CommandLineRunner interface provides a useful way of picking up command line arguments once the application has started, but it won’t help change the nature of the application. As you’ve probably discovered, the application will probably not exit since it thinks it needs to handle incoming web requests.

The approach you’ve taken in your main method looks sensible to me. You need to tell Spring Boot that it isn’t a web application, and therefor shouldn’t hang around listening for incoming requests once it’s been started.

I’d do something like this:

public static void main(String[] args) {
    SpringApplication application = new SpringApplication(AutoDbServiceApplication.class);
    application.setWeb(ObjectUtils.isEmpty(args);
    application.run(args);
}

That should start the application in the correct mode. Then you can use a CommandLineRunner bean in the same way as you currently do. You might also want to look at ApplicationRunner which has a slightly better API:

@Component
public class AutoDbApplicationRunner implements ApplicationRunner {

    public void run(ApplicationArguments args) {
        if (ObjectUtils.isEmpty(args.getSourceArgs)) {
            return; // Regular web application
        }
        // Do something with the args.
        if (args.containsOption(“foo”)) {
            // …
        }
    }

}

If you really don’t want the AutoDbApplicationRunner bean to even be created you could look at setting a profile in the main method that you could use later (see SpringApplication.setAdditionalProfiles).

like image 20
Phil Webb Avatar answered Nov 15 '22 18:11

Phil Webb