使用DefaultParser而不是GnuParser时,为什么检测到的CLI选项不同?

MWi*_*ner 24 java command-line-interface apache-commons apache-commons-cli

我即将迁移某些遗留代码含有较少的过时的警告,第三次三方库.对于Apache commons-cli库(版本:1.3.1),我在官方JavaDoc中检测到GnuParser已弃用,DefaultParser应该使用:

@deprecated自1.3以来,使用{@link DefaultParser}而不是

但是,以下代码段停止按预期方式工作:

Options options = new Options();    
Option optionGSTypes = new Option(
        "gst","gs-types", true,
        "the supported types, comma-separated: article, category, template, all");
optionGSTypes.setArgs(3);
optionGSTypes.setValueSeparator(',');
options.addOption(optionGSTypes);

// ... other options

// parsed option values are correct, yet this is deprecated
CommandLineParser parser = new GnuParser(); 
CommandLine commands = parser.parse(options, args);

// ... interpret parsed 'commands' and related actual values via CLI
Run Code Online (Sandbox Code Playgroud)

请注意,setValueSeparator(',')此处用于定义自定义分隔符char ,以使CLI能够支持sevaral gst -types(请参阅代码段).

作为输入,以下程序参数用于调用CLI:

java -jar MyCLI.jar -gst category -gsd 4

显然,在gsd参数之后也可能添加了其他几个参数.无分隔符使用"gst"参数的预期和正确解析选项是(via GnuParser):

  1. "类别"(没有别的)

但是,当我更改我的代码并通过以下方式切换到推荐的解析器时:

CommandLineParser parser = new DefaultParser();
Run Code Online (Sandbox Code Playgroud)

生成的,已解析的值被错误地检测为:

  1. "类别"
  2. "-gsd"
  3. "4"

提示:我使用的调试器通过检查字段来验证解析过程的不正确的结果valuesorg.apache.commons.cli.Option通过返回的commands变量.

我的期望是,解析器的内部变化应该不会产生不同的结果,因为这打破现有的代码.切换到DefaultParser多个选项值和自定义分隔符时,有没有人遇到过与Apache Commons-CLI相同的行为?

DefaultParser我可能会监督的建筑/用途有什么不同吗?

Sve*_*ung 8

单步执行代码DefaultParser,这似乎是一个错误.

首先通过调用哪个返回来DefaultParser识别-gst为短选项.Options.hasShortOption("-gst")true

到现在为止还挺好.

现在,当决定是否将其解释-gsd为参数值时,-gst DefaultParser需要弄清楚if -gsd本身是否是一个选项(因此不能成为参数-gst).它通过调用它自己来实现isShortOption("-gsd").然而false,如果您查看代码,这会返回原因:

private boolean isShortOption(String token)
{
    // short options (-S, -SV, -S=V, -SV1=V2, -S1S2)
    return token.startsWith("-") && token.length() >= 2 && 
           options.hasShortOption(token.substring(1, 2));
}
Run Code Online (Sandbox Code Playgroud)

这将从-gst选项中提取第一个字母,从而调用Options.hasShortOption("g")哪个返回false.该代码似乎是为POSIX风格的单字母选项设计的,但是对于你使用的多字母单连字符选项而言它会分解.

然而你转过来,-gst被认为是一个简短的选项,但-gsd 没有得到认可似乎是一个错误给我.


cen*_*tic 1

我认为问题可能是对 的调用optionGSTypes.setArgs(3);,根据 JavaDoc 它指示 commons-cli “设置此选项可以采用的参数值的数量。”,即指示 commons-cli 将接下来的三个 commnadline 参数作为参数对于“gst”论点。

另外,setValueSeparator(',')似乎定义了等号通常的用途(请参阅JavaDoc),即格式如“key=value”的选项,所以不是您实际要寻找的。

在你的情况下,我认为最简单的选择是将选项参数指定为简单字符串并自己进行解析。通过这种方式,您可以完全控制允许哪些值,并提供更好的错误消息。

  • 那么它要么是“DefaultParser”中的错误,要么是“GnuParser”中的“未记录”行为,在这两种情况下,您可能需要直接与 commons-cli 的维护者讨论,因为只有他们才能说明两者中的哪一个情况确实如此。 (3认同)
  • Apache 项目总是有此类讨论的邮件列表,因此您最好的选择就是在那里发帖,然后维护人员肯定会看到这个问题。请参阅http://commons.apache.org/proper/commons-cli/mail-lists.html (2认同)