“This is the third day of my participation in the November Gwen Challenge. See details of the event: The last Gwen Challenge 2021”.

Jar package execution when passing the use of posture

Although most of us do not directly use jar package to run, at present it is more mainstream to throw our services into a container (such as Tomcat, Jetty, etc.). For example, the e-commerce company I worked for before packaged the project into WAR package and threw it into tomcat container to run

When using SpringBoot, it is possible to package an executable JAR and then run it. In this case, Java commands can be used to pass arguments, so the question is, how can the main method gracefully parse these arguments?

I. Crude version

The easiest way to think about it is to parse the main method’s pass-throughs

public static void main(String[] args) {}Copy the code

As you can easily guess from the above, the parameters passed in end up in the args array, so use it however you want. An example of hello World is as follows

public static void main(String[] args) {
	System.out.println("hello " + args[0]);
}
Copy the code

The tests are as follows:

See here, really feel that there is no dry goods, the above is too small white, it is estimated that even the entry is not, so parameter processing only stop here?

II. Advanced versions

The man command can be used to check the help of many shell commands. It introduces many parameters of shell commands, and these parameters are generally abbreviated and spelled in full. Some parameters can be passed with values, while others are not needed. It already has its own set of specifications, and it’s very cool to use

So can our JAR package support this way of passing parameters?

As a simple example, the HelloWord above accepts a simple username argument

  • If not passed, hello World is printed by default
  • Short parameter mode:-n xxx
  • Long parameter mode:--name=xxx

To support just one scenario and parse it yourself, you need to write a long list of code, but the requirement is already on wheels

1. commons-cli

First introduce dependencies

<dependency>
    <groupId>commons-cli</groupId>
    <artifactId>commons-cli</artifactId>
    <version>1.3.1</version>
</dependency>
Copy the code

Start to use, the official website has given examples, you can refer to the complete DOC

  • commons-cli Usage Scenarios

2. Example demonstration

The following is a combination of my project, the actual use of the way

@Slf4j
public class AppLaunch {
    private static final String SOURCE_PATH = "./task-core/src/test/java/com/git/hui/task";
    private static final String TASK_ARG_LONG = "task";
    private static final String TASK_ARG_SHORT = "t";
    private static final String ARG_HELP_LONG = "help";
    private static final String ARG_HELP_SHORT = "h";
    private static volatile boolean run = true;


    private static void printHelp(a) {
        Options options = buildOptions();
        HelpFormatter helpFormatter = new HelpFormatter();
        helpFormatter.printHelp("java -jar ${jar} [options]", options);
    }

    private static Options buildOptions(a) {
        Options options = new Options();
        options.addOption(
                Option.builder(TASK_ARG_SHORT).argName(TASK_ARG_LONG).hasArg().longOpt(TASK_ARG_LONG).required(false)
                        .desc("choose task path, default [" + SOURCE_PATH + "]").build());
        options.addOption(Option.builder(ARG_HELP_SHORT).longOpt(ARG_HELP_LONG).desc("show command help").build());
        return options;
    }

    private static CommandLine parseArguments(String[] arguments) {
        Options options = buildOptions();
        CommandLine commandLine = null;
        try {
            commandLine = new DefaultParser().parse(options, arguments);
        } catch (ParseException e) {
            e.printStackTrace();
            System.exit(1);
        }

        if (commandLine.hasOption(ARG_HELP_LONG)) {
            printHelp();
            System.exit(0);
        }
        return commandLine;
    }


    public static void main(String[] args) throws InterruptedException {
        CommandLine commandLine = parseArguments(args);
        String scriptSource = commandLine.getOptionValue(TASK_ARG_LONG, SOURCE_PATH);
        System.out.println("script source: {}" + scriptSource);
        / /...}}Copy the code

The above use posture for a simple explanation, from the logical division, can be divided into the following several pieces

  • Define the parameters, including parameter description, abbreviation and full spelling, whether there are parameter values, description, etc
  • Parses the pass parameter group, parsing the specific pass parameter asCommandLineobject
  • Gets the parameters and executes the corresponding business logic

There’s nothing complicated or hard to understand from a source point of view, but the definition of the parameters is, in the buildOption method, we specify two parameters help and task, one of which requires a parameter value and one of which does not

III. The other

0. Information

  • Documentation: Commons – CLI User manual
  • Actual project: github.com/liuyueyi/qu…

1. Gray contact information

All letter is better than no book, the above content, purely one’s words, due to the limited personal ability, it is hard to avoid omissions and mistakes, such as finding bugs or better suggestions, welcome criticism and correction, not grudging gratitude

  • Personal site: blog.hhui.top
  • Micro Blog address: Small Gray Blog
  • QQ: a gray /3302797840
  • Wechat official account: One Grey Blog