24

我即将迁移一些遗留代码以包含来自3rd方库的较少弃用的警告。对于 Apachecommons-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

请注意,setValueSeparator(',')此处用于定义自定义分隔符,,以使 CLI 支持多种gst类型(请参阅代码片段)。

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

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

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

  1. “类别”(仅此而已)

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

CommandLineParser parser = new DefaultParser();

结果,解析的值被错误地检测为:

  1. “类别”
  2. “-gsd”
  3. “4”

提示:我使用调试器通过检查返回变量values中的字段来验证解析过程的错误结果。org.apache.commons.cli.Optioncommands

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

DefaultParser我可能监督的构造/使用有什么不同吗?

4

2 回答 2

8

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

First通过调用which returns 将其DefaultParser识别-gst为短选项。Options.hasShortOption("-gst")true

到目前为止,一切都很好。

现在,在决定是否将其解释-gsd为参数值时,-gst DefaultParser需要弄清楚-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));
}

这会从选项中提取第一个字母,-gst因此调用Options.hasShortOption("g")which 返回false。该代码似乎设计为适用于 POSIX 样式的单字母选项,但它会分解为您正在使用的多字母单连字符选项。

不管你怎么转,-gst得到认可是一个短暂的选择,但-gsd 没有得到认可对我来说似乎是一个错误。

于 2016-02-13T18:30:46.103 回答
1

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

此外,setValueSeparator(',')似乎定义了等号通常用于什么,(参见JavaDoc),即格式为“key=value”的选项,因此不是您真正要查找的。

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

于 2016-01-01T16:19:07.283 回答