javacommand-line-interfaceapache-commonsapache-commons-cli

Apache Commons CLI: no exception thrown after passing illegal arguments to options


My problem is that I don't see an any exception thrown when an option that should accept no argument is given an argument.

Just standard setup, straight from the documentation

Options options = new Options();
CommandLineParser parser = new DefaultParser();
CommandLine cmd;

option:

Option op = Option.builder("op")
                  .longOpt("op")
                  .hasArg(false)
                  .desc("bla")
                  .build();
options.addOption(op);

try-catch:

try {
    cmd = parser.parse(options, args);
    if (cmd.hasOption("op") { //do something }
} catch (ParseException | IllegalArgumentException exp) {
    System.err.println(exp.getMessage());
    System.exit(0);
}

I've tried every method that seems relevant provided in the Option.Builder class(link), but none of them throws an exception at -op with an argument, say, -op hello

Is there an exception class that handles illegal arguments of options in Apache Commons CLI or do we have to manually do so? (then what's the point of having a method like hasArg(boolean hasArg)? )


Solution

  • Commons CLI by supports "trailing arguments", i.e. <options> arg1 [arg2...].

    If you look at getArgs() or getArgList() you see that the option did not parse the value and so it ended up in the list of trailing arguments.

        Option op = Option.builder("op")
                .longOpt("op")
                .hasArg(false)
                .desc("bla")
                .build();
    
        Options options = new Options();
        options.addOption(op);
    
        CommandLineParser parser = new DefaultParser();
        CommandLine cmd = parser.parse(options, new String[] {"-op", "bla"});
        assertTrue(cmd.hasOption(op));
    
        assertEquals("[bla]", cmd.getArgList().toString());
        assertEquals("[bla]", Arrays.toString(cmd.getArgs()));
    

    I did not find a way to disallow such trailing arguments.

    So if you want to fail when this happens, you can check and throw an exception if getArgs() returns a non-empty array.