Picocli 没有在每次执行时重置收集字段?
Picocli not resetting collection field on each execution?
我最近将我的项目升级到 Picocli 4.2.0,包括删除所有已弃用的方法调用,并且我一直在继续我描述的工作 。我 运行 又遇到了同样的问题 -- 我有一个字段似乎没有重置。这与我的其他问题唯一不同的是,现在该字段是一个集合。代码如下所示:
@Command(name="watch", description="Alters the set of watched productions", subcommands={HelpCommand.class})
static public class Watch implements Runnable
{
@ParentCommand
ProductionC parent; // injected by picocli
@Option(names={"on", "-e", "--on", "--enable"}, description="Enables watching of given productions")
List<String> productionsToEnable;
@Option(names={"off", "-d", "--off", "--disable"}, description="Disables watching of given productions")
List<String> productionsToDisable;
@Override
public void run()
{ ... }
(完整代码可用 here。)
具体来说,productionsToEnable
似乎没有重置。调用的方式是单元测试的一部分:
@Test
public void testCanListTracedRules() throws Exception
{
loadRules();
agent.getInterpreter().eval("production watch --on b");
agent.getInterpreter().eval("production watch --on c");
final StringWriter result = new StringWriter();
agent.getPrinter().pushWriter(result);
agent.getInterpreter().eval("production watch");
agent.getPrinter().popWriter();
assertEquals("b\nc", result.toString());
}
(完整代码可用 here。)
当上次 eval
调用 production watch
命令时,上次调用 production watch
的字符串 "c"
仍然存在于 productionsToEnable
中。
请注意,上面的代码链接位于 jsoar-command-performance
分支上,以备仔细查看。
picocli 4.2.0 中有一个回归,这意味着当 CommandLine
实例被重用时,子命令中 @Option
注释的字段不会重置为它们的初始值。
此问题已在 this ticket 的 picocli 项目问题跟踪器中进行跟踪。 (状态 2020-04-20:已在 master 中修复。)
范围
使用 picocli 4.2.0,调用之间不会清除子命令选项。这会影响 在多次调用中重复使用 CommandLine
实例的应用程序 。如果某个选项在第一次调用中指定而在第二次调用中省略,它将错误地保留第一次调用的值。
在JVM 进程中只调用一次子命令时,问题不会出现。此外,不重用 CommandLine
实例的应用程序和没有子命令的应用程序不受影响。
该问题在4.2.0版本中引入,在picocli 4.1.4及更早版本中不存在。
解决方法
此回归不适用于在注释中定义了 defaultValue
的选项:定义为 @Option(... defaultValue="...")
的选项将在多次调用之间正确重置为默认值。尽可能使用 defaultValue 注释。
原因
原因与最近对 lazy subcommand instantiation and repeatable subcommands 的更改有关。
picocli 问题跟踪器上的 ticket 有更多详细信息和进度更新。
我最近将我的项目升级到 Picocli 4.2.0,包括删除所有已弃用的方法调用,并且我一直在继续我描述的工作
@Command(name="watch", description="Alters the set of watched productions", subcommands={HelpCommand.class})
static public class Watch implements Runnable
{
@ParentCommand
ProductionC parent; // injected by picocli
@Option(names={"on", "-e", "--on", "--enable"}, description="Enables watching of given productions")
List<String> productionsToEnable;
@Option(names={"off", "-d", "--off", "--disable"}, description="Disables watching of given productions")
List<String> productionsToDisable;
@Override
public void run()
{ ... }
(完整代码可用 here。)
具体来说,productionsToEnable
似乎没有重置。调用的方式是单元测试的一部分:
@Test
public void testCanListTracedRules() throws Exception
{
loadRules();
agent.getInterpreter().eval("production watch --on b");
agent.getInterpreter().eval("production watch --on c");
final StringWriter result = new StringWriter();
agent.getPrinter().pushWriter(result);
agent.getInterpreter().eval("production watch");
agent.getPrinter().popWriter();
assertEquals("b\nc", result.toString());
}
(完整代码可用 here。)
当上次 eval
调用 production watch
命令时,上次调用 production watch
的字符串 "c"
仍然存在于 productionsToEnable
中。
请注意,上面的代码链接位于 jsoar-command-performance
分支上,以备仔细查看。
picocli 4.2.0 中有一个回归,这意味着当 CommandLine
实例被重用时,子命令中 @Option
注释的字段不会重置为它们的初始值。
此问题已在 this ticket 的 picocli 项目问题跟踪器中进行跟踪。 (状态 2020-04-20:已在 master 中修复。)
范围
使用 picocli 4.2.0,调用之间不会清除子命令选项。这会影响 在多次调用中重复使用 CommandLine
实例的应用程序 。如果某个选项在第一次调用中指定而在第二次调用中省略,它将错误地保留第一次调用的值。
在JVM 进程中只调用一次子命令时,问题不会出现。此外,不重用 CommandLine
实例的应用程序和没有子命令的应用程序不受影响。
该问题在4.2.0版本中引入,在picocli 4.1.4及更早版本中不存在。
解决方法
此回归不适用于在注释中定义了 defaultValue
的选项:定义为 @Option(... defaultValue="...")
的选项将在多次调用之间正确重置为默认值。尽可能使用 defaultValue 注释。
原因
原因与最近对 lazy subcommand instantiation and repeatable subcommands 的更改有关。
picocli 问题跟踪器上的 ticket 有更多详细信息和进度更新。