Reputation: 167
I'm using Apache Commons CLI 1.3.1 to process some options and some of the options can take one to unlimited number arguments. A trivia example with two options would be like this
usage: myProgram -optionX <arg1> <arg2> <arg3> < ... > [-optionY]
-optionX <arg1> <arg2> <arg3> < ... > optionX takes one to unlimited
number of arguments.
-optionY optionY is optional
What I found is that the second option optionY
is always recognized as an ARGUMENT of the optionX
instead of being recognized as an OPTION by itself. That means if you type
myProgram -optionX arg1 arg2 -optionY
in the command line, you will get three arguments (arg1
, arg2
, and -optionY
) associated with optionX
.
Here is the code that anyone can use to reproduce the problem.
import org.apache.commons.cli.*;
public class TestCli {
public static void main(String[] args) {
Option optObj1 = Option.builder("optionX")
.argName("arg1> <arg2> <arg3> < ... ")
.desc("optionX takes one to unlimited number of arguments.")
.required()
.hasArgs()
.build();
Option optObj2 = new Option("optionY", "optionY is optional");
Options optsList = new Options();
optsList.addOption(optObj1);
optsList.addOption(optObj2);
CommandLineParser commandLineParser = new DefaultParser();
try {
CommandLine cmd = commandLineParser.parse(optsList, new String[]{"-optionX", "arg1", "arg2", "-optionY"});
System.out.println("--------------------------");
System.out.println("argument list of optionX: ");
for (String argName : cmd.getOptionValues(optObj1.getOpt())) {
System.out.println("arg: " + argName);
}
System.out.println("--------------------------");
System.out.println("value of optionY: " + cmd.hasOption(optObj2.getOpt()));
} catch (ParseException e) {
System.out.println("Unexcepted option: " + e.getMessage());
}
}
}
This is the output you'll see.
--------------------------
argument list of optionX:
arg: arg1
arg: arg2
arg: -optionY
--------------------------
value of optionY: false
Do I miss something here?
Any suggestion will be really appreciated.
Upvotes: 2
Views: 1203
Reputation: 141
The problem is that you are putting the long name in the short name of the option.
When you use Option optObj1 = Option.builder("optionX")....
or new Option("optionY", "optionY is optional")
, you're setting the short name of the option, which is supposed to be only 1 character long.
That work well until you have a multi arguments option. In this case, the parser cannot find "o" (the first letter of your option) in his short option list and you don't have a long name set, so the parser determines that -optionY is just another argument for -optionX.
To solve your problem, just set the long option name of your option and it should work alright.
Example
Option.builder("x").longOpt("optionX")....
Option optObj2 = new Option("y", "optionY", hasArgs, "optionY is optional");
Upvotes: 4