Java 当用户只想打印使用情况时,如何避免所需选项的ParserException?

Java 当用户只想打印使用情况时,如何避免所需选项的ParserException?,java,apache-commons-cli,Java,Apache Commons Cli,因此,我有一个Options实例,在其他选项中有一个(注意isRequired()): options.addOption(OptionBuilder .使用LongOpt(“seq1”) .带说明(“必需:废话废话”) .hasArg().isRequired().create()); options.addOption(OptionBuilder .使用LongOpt(“seq2”) .带说明(“必填项:blih blih”) .hasArg().isRequired().create())

因此,我有一个
Options
实例,在其他选项中有一个(注意
isRequired()
):

options.addOption(OptionBuilder
.使用LongOpt(“seq1”)
.带说明(“必需:废话废话”)
.hasArg().isRequired().create());
options.addOption(OptionBuilder
.使用LongOpt(“seq2”)
.带说明(“必填项:blih blih”)
.hasArg().isRequired().create());
options.addOption(新选项(“?”,“帮助”),false,
“打印此消息并退出”);
当我调用
parser.parse(args)
时,如果
seq1
seq2
不存在,parse(args)会引发异常-但我想让它打印我的消息而不引发异常-如何处理?这会在
行中抛出NPE。hasOption(“帮助”)
,自然:

CommandLine=null;
试一试{
CommandLineParser=new GnuParser();
//解析命令行参数
line=parser.parse(选项、参数);
}捕获(解析异常){
if(line.haspoption(“help”){//NPE
用法(0);
}
System.err.println(“解析失败。原因:+e.getMessage());
用法(1);
}
专用静态无效用法(int-exitCode){
//自动生成帮助语句
HelpFormatter formatter=新的HelpFormatter();
printHelp(“Smith Waterman”,选项,true);
系统退出(退出代码);
}

正如您所发现的,Commons CLI不处理选项间依赖关系。在您的情况下,
--help
选项修改了
seq1
seq2
的要求


唯一真正的解决方案是将所有选项设为非必需选项,并在命令行解析完成后自己进行依赖项验证。

这可能有用,也可能无效,具体取决于您的使用情况。我的发言如下:

  • 我有一个包装程序(称为“控制器”)
  • 控制器可以运行许多命令(称为“任务”)
  • 每个命令都有自己的一组唯一命令行参数集
例如:

$ controller startall -rsrc foo -dir bar -where baz
使用参数所做的第一件事是确定命令是什么。为此,我设置了一个TaskFactory,它查看第一个参数,去掉所有前导连字符,然后查找它,看看它是否是一个已知任务。我有一个“帮助”任务,它允许我的用户执行以下操作:

$ controller -help

每个任务都有一个帮助选项,因此用户可以执行以下操作:

$ controller startall -help

不过,这可能对你没有帮助。我将发布另一个选项。

扩展您选择的解析器以忽略未知选项:

然后分析两次参数,一次用于
-help
参数,一次用于普通参数。第一次通过时,您应该传递“忽略”标志,第二次不应该传递

或者,对选项进行两次解析,一次查找
-help
并捕获(并忽略)
MissingOptionException
,然后再次使用常规参数进行解析。

解决方案改编自


如果有更优雅的东西出现,我会很乐意接受它

我在解析之前使用了以下检查,以确保
-h
-help
可以推翻其他所有内容

// check if help is requested
if (Arrays.asList(args).contains("-h")
        || Arrays.asList(args).contains("--help")) {
    usage(0); // print usage with exit 0
}
// parse options

虽然不是最好的解决方案,但它满足了我的需要。

当parser.parse()抛出ParseException时,不会返回任何值。这就是java异常的工作方式。因此,您可能必须亲自检查原始参数,以查看“帮助”选项是否已通过。@GreyB:我知道(请自然注意)-我确信一定有另一种方法——事实上我找到了一个解决办法,但我希望有更博学的人会回答——否则我会将我的解决办法发布为答案不正确——有一种方法,但我并不真正满意——将发布它,尽管没有人提出更优雅的东西,但在
--help
添加在末尾
command--seq1--help
会给我一个
MissingArgumentException
我在解析之前做了一个小检查now@superbly考虑报告并将链接从报告中发回
private static final Options OPTIONS = new Options();
private static final Options HELP_OPTIONS = new Options();
OPTIONS.addOption(OptionBuilder
        .withLongOpt("seq1")
        .withArgName("file1")
        .withDescription(
                "REQUIRED : the file containing sequence 1")
        .hasArg().isRequired().create());
// etc
final Option help = new Option("?", "help", false,
        "print this message and exit");
HELP_OPTIONS.addOption(help);
OPTIONS.addOption(help);
// later
CommandLineParser parser = new GnuParser();
CommandLine line = parser.parse(HELP_OPTIONS, args, true); // true so it
// does not throw on unrecognized options
if (line.hasOption("help")) {
    usage(0); // calls exit
}
line = parser.parse(OPTIONS, args);
// check if help is requested
if (Arrays.asList(args).contains("-h")
        || Arrays.asList(args).contains("--help")) {
    usage(0); // print usage with exit 0
}
// parse options