Java Apache CLI Необязательные аргументы командной строки не работают

Пытаясь использовать Apache Commons Command Line Interface 1.3.1 отсюда он отлично работает для обязательных аргументов, но, кажется, отбрасывает любые необязательные аргументы. Может кто-нибудь определить проблему с моим кодом ниже?

import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.DefaultParser;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;

public class TestCommandLine {

    public static void main(String[] args) {

        // *****  test with command line arguments -R myfirstarg -O mysecondarg  *****
        // *****  the second arg is not being captured                          *****

        System.out.println("Number of Arguments : " + args.length);

        String commandline = "";
        for (String arg : args) {
            commandline = commandline + (arg + " ");
        }
        commandline.trim();
        System.out.println("Command-line arguments: " + commandline);

        // create Options object
        Options options = new Options();
        options.addOption("R", true, "Enter this required argument");
        Option optionalargument = Option.builder("O")
                .optionalArg(true)   // if I change this line to .hasArg(true) it works, but then is not optional
                .desc("Enter this argument if you want to")
                .build();
        options.addOption(optionalargument);

        // initialize variables used with command line arguments
        String firstargument = null;
        String secondargument = null;


        CommandLineParser parser = new DefaultParser();
        try {
            // parse the command line arguments
            CommandLine cmd = parser.parse( options, args );

            firstargument = cmd.getOptionValue("R");
            secondargument = cmd.getOptionValue("O");

            if(cmd.hasOption("R")){
                if(firstargument == null){
                    System.out.println("Must provide the first argument  ...  exiting...");
                    System.exit(0);
                }
                else {
                    System.out.println("First argument is " + firstargument);
                }
            }
            if(cmd.hasOption("O")) {
                // optional argument
                if (secondargument == null){
                    System.out.println("Second argument is NULL");
                }
                else{
                    // should end up here if optional argument is provided, but it doesn't happen
                    System.out.println("Second argument is " + secondargument);
                }
            }

        }
        catch( ParseException exp ) {
            // oops, something went wrong
            System.err.println( "Parsing failed.  Reason: " + exp.getMessage() );
        }
    }

}

Выход из вышеприведенного кода:

Number of Arguments : 4
Command-line arguments: -R myfirstarg -O mysecondarg 
First argument is myfirstarg
Second argument is NULL

Почему "mysecondarg" не попадает в плен? Если я изменю строку.optionalArg(true) на.hasArg(true), тогда будет захвачен второй аргумент, но вся идея состоит в том, чтобы иметь возможность опционально опустить второй аргумент.

3 ответа

Решение

Кажется, вам нужно установить numberOfArgs в дополнение к hasOptionalArgs, чтобы он работал правильно.

Есть еще один метод parse(), который принимает третий параметр param - stopAtNonOption.

Установка false для stopAtNonOption приведет к сбою синтаксического анализа, выдаче и исключению при достижении неизвестного параметра.

Я обнаружил, что синтаксический анализатор прекращает синтаксический анализ, когда он достигает неизвестного параметра.

Apache Command-CLI слишком многословен, что вызывает недопонимание и проблемы. Для него можно использовать удобную обертку:

      <dependency>
    <groupId>com.github.bogdanovmn.cmdline</groupId>
    <artifactId>cmdline-app</artifactId>
    <version>3.0.0</version>
</dependency>

Исходный код будет выглядеть так (работает так, как вы ожидали):

      import com.github.bogdanovmn.cmdline.CmdLineAppBuilder;

public class TestCommandLine {
    public static void main(String[] args) throws Exception {
        new CmdLineAppBuilder(args)
            .withArg("R", "Enter this required argument").required()
            .withArg("O", "Enter this argument if you want to")
            .withEntryPoint(options -> {
                // The R arg is required, we shouldn't check it is specified
                System.out.println("First argument is " + options.get("R"));
                if (options.has("O")) {
                    String secondargument = options.get("O");
                    if (secondargument == null) {
                        // Will never go here
                        System.out.println("Second argument is NULL");
                    } else{
                        // should end up here if optional argument is provided
                        System.out.println("Second argument is " + secondargument);
                    }
                }
            })
        .build().run();
    }
}

Он выдаст исключение во время выполнения в случае командной строки аргументов «-R myfirstarg -O»:

      java.lang.RuntimeException: Missing argument for option: O

Дополнительную информацию см. в документации.

Другие вопросы по тегам