我即将迁移一些遗留代码,以包含来自 3rd -party库的较少弃用警告。对于Apache commons-cli
库(版本: 1.3.1 ),我在official JavaDoc中检测到GnuParser
已弃用且应使用DefaultParser
:
自1.3以来@deprecated,使用
{@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(',')
来定义自定义分隔符char ,
,以使CLI能够支持sevaral gst -types(请参阅代码段)。
作为输入,以下程序参数用于调用CLI:
java -jar MyCLI.jar -gst category -gsd 4
显然,在gsd参数之后也可能添加了其他几个参数。对于" gst"的无分隔符使用的预期和正确解析选项。参数是(通过GnuParser
):
但是,当我更改我的代码并通过以下方式切换到推荐的解析器时:
CommandLineParser parser = new DefaultParser();
生成的,已解析的值错误地检测为:
提示:我使用调试器通过返回的values
变量检查org.apache.commons.cli.Option
中的字段commands
来验证解析过程的错误结果。
我的期望是解析器的内部更改应不产生不同的结果,因为这会破坏现有代码。切换到DefaultParser
以及多个选项值和自定义分隔符时,有没有人遇到过与Apache Commons-CLI相同的行为?
我可能会监督DefaultParser
的构造/用法是否存在差异?
答案 0 :(得分:8)
单步执行DefaultParser
的代码,这似乎是一个错误。
首先DefaultParser
通过调用返回-gst
的{{3}}来将true
视为简短选项。
到目前为止一切顺利。
现在,当决定是否将-gsd
解释为-gst
DefaultParser
的参数值时,需要确定-gsd
本身是否是一个选项(因此可以& #39; t是-gst
的参数。它通过调用自己的Options.hasShortOption("-gst")
来实现。然而,这会返回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")
的{{1}}。该代码似乎是为POSIX风格的单字母选项设计的,但是对于多字母单连字符选项(例如您正在使用的选项)而言它会被分解。
无论你转过它,false
都被认为是一个简短的选项,但-gst
而不是被识别似乎对我来说是一个错误。
答案 1 :(得分:1)