您可以在此处找到代码示例。 Link to my GitHub project
在Driver.java文件中,您可以看到我指定了一个排他的ArgGroup。根据文档,我的理解是默认多重性是0.1.1。该文档指出:“默认值为multiplicity =“ 0..1”,这意味着默认情况下可以省略或指定一次组。”
我还尝试将多重性显式设置为0..1,但这并没有改变行为。运行不带-al或-rl选项的程序,解析将引发NullPointerException。该框架的行为似乎是其中之一。这与documentation不符。如果需要,我应该只能使用-n选项运行该程序。我希望ArgGroup是完全可选的。
git枢纽链接处的程序是一个功能全面的maven项目,可以克隆,构建和运行。但是,这是堆栈跟踪。没有指定参数或没有arg组。我希望在没有任何参数的情况下将打印用法信息。另外,该组的默认多重性应为0..1,因此我不必在arg组中指定一个选项。
java.lang.NullPointerException
at com.shawnfox.java4.concurrency.Driver.call(Driver.java:58)
at com.shawnfox.java4.concurrency.Driver.call(Driver.java:1)
at picocli.CommandLine.executeUserObject(CommandLine.java:1743)
at picocli.CommandLine.access$900(CommandLine.java:145)
at picocli.CommandLine$RunLast.handle(CommandLine.java:2101)
at picocli.CommandLine$RunLast.handle(CommandLine.java:2068)
at picocli.CommandLine$AbstractParseResultHandler.execute(CommandLine.java:1935)
at picocli.CommandLine.execute(CommandLine.java:1864)
at com.shawnfox.java4.concurrency.Driver.main(Driver.java:50)
答案 0 :(得分:1)
感谢您添加堆栈跟踪。我看到NullPointerException
发生在line 58的call
方法中,而不是picocli本身。
所以问题不在于picocli需要可选的(multiplecity = 0..1
)参数组中的选项,问题在于call
方法假定带有@ArgGroup
注释的字段将即使组中没有选项匹配,也总是初始化。这个假设是错误的。
发生的事情是,如果在命令行上既未指定-al
选项也未指定-rl
选项,则SynchronizationOptions
参数组根本不匹配,因此picocli将不会实例化SynchronizationOptions
对象,并且synchOptions
field on line 32将不会初始化。
这是picocli解析器与参数组一起工作的方式:例如,对于具有多重性*
的组,picocli将为每个组匹配创建用户对象的实例,并将其添加到带注释的集合/数组中字段。
如果没有匹配的组,则该用户对象的实例将为零。这使应用程序可以准确地检测出该组是否匹配-如果该组匹配,则该应用程序可以依赖于唯一组 的不变性。 option已匹配并具有值,并且对于同现组 all 选项已匹配并具有命令行中的值。 (如果picocli实例化不匹配的用户对象,则不可能。)
解决方案是将应用程序更改为检查null
或初始化应用程序中的synchOptions
字段。后者可能是最简单,最干净的。例如,替换:
@ArgGroup(exclusive = true)
SynchronizationOptions synchOptions;
与
@ArgGroup(exclusive = true)
SynchronizationOptions synchOptions = new SynchronizationOptions();
然后synchOptions
永远不会null
,因此应用程序可以安全地在call
方法中引用其字段:
public Void call() {
if (synchOptions.useReentrantLock) {
// ...
或者,检查是否使用synchOptions == null
方法中的call
。这样,应用程序可以检测是否有任何同步选项匹配,如果匹配,则应用程序可以依赖以下事实:至少一个布尔字段为true
。