Intelli/J incremental compilation gives this error. (Unsure if this can be reproduced with Gradle.)
Looks like this was only partially fixed (if at all) in #794.
Steps to reproduce:
Error:java: FATAL ERROR: picocli.CommandLine$InitializationException: ArgGroup has no options or positional parameters, and no subgroups: AnnotatedElementHolder(FIELD myGroup in repeating.subcommands.Sub) in null
at picocli.CommandLine$Model$ArgGroupSpec.<init>(CommandLine.java:9449)
at picocli.CommandLine$Model$ArgGroupSpec$Builder.build(CommandLine.java:9893)
at picocli.codegen.annotation.processing.AbstractCommandSpecProcessor$Context.connectArgGroups(AbstractCommandSpecProcessor.java:954)
at picocli.codegen.annotation.processing.AbstractCommandSpecProcessor$Context.connectModel(AbstractCommandSpecProcessor.java:832)
at picocli.codegen.annotation.processing.AbstractCommandSpecProcessor$Context.access$000(AbstractCommandSpecProcessor.java:783)
at picocli.codegen.annotation.processing.AbstractCommandSpecProcessor.tryProcess(AbstractCommandSpecProcessor.java:185)
at picocli.codegen.annotation.processing.AbstractCommandSpecProcessor.process(AbstractCommandSpecProcessor.java:156)
at com.sun.tools.javac.processing.JavacProcessingEnvironment.callProcessor(JavacProcessingEnvironment.java:794)
at com.sun.tools.javac.processing.JavacProcessingEnvironment.discoverAndRunProcs(JavacProcessingEnvironment.java:705)
at com.sun.tools.javac.processing.JavacProcessingEnvironment.access$1800(JavacProcessingEnvironment.java:91)
at com.sun.tools.javac.processing.JavacProcessingEnvironment$Round.run(JavacProcessingEnvironment.java:1035)
at com.sun.tools.javac.processing.JavacProcessingEnvironment.doProcessing(JavacProcessingEnvironment.java:1176)
at com.sun.tools.javac.main.JavaCompiler.processAnnotations(JavaCompiler.java:1170)
at com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:856)
at com.sun.tools.javac.main.Main.compile(Main.java:523)
at com.sun.tools.javac.api.JavacTaskImpl.doCall(JavacTaskImpl.java:129)
at com.sun.tools.javac.api.JavacTaskImpl.call(JavacTaskImpl.java:138)
at org.jetbrains.jps.javac.JavacMain.compile(JavacMain.java:207)
at org.jetbrains.jps.incremental.java.JavaBuilder.compileJava(JavaBuilder.java:493)
at org.jetbrains.jps.incremental.java.JavaBuilder.compile(JavaBuilder.java:345)
at org.jetbrains.jps.incremental.java.JavaBuilder.doBuild(JavaBuilder.java:270)
at org.jetbrains.jps.incremental.java.JavaBuilder.build(JavaBuilder.java:223)
at org.jetbrains.jps.incremental.IncProjectBuilder.runModuleLevelBuilders(IncProjectBuilder.java:1414)
at org.jetbrains.jps.incremental.IncProjectBuilder.runBuildersForChunk(IncProjectBuilder.java:1092)
at org.jetbrains.jps.incremental.IncProjectBuilder.buildTargetsChunk(IncProjectBuilder.java:1159)
at org.jetbrains.jps.incremental.IncProjectBuilder.buildChunkIfAffected(IncProjectBuilder.java:1053)
at org.jetbrains.jps.incremental.IncProjectBuilder.buildChunks(IncProjectBuilder.java:882)
at org.jetbrains.jps.incremental.IncProjectBuilder.runBuild(IncProjectBuilder.java:449)
at org.jetbrains.jps.incremental.IncProjectBuilder.build(IncProjectBuilder.java:190)
at org.jetbrains.jps.cmdline.BuildRunner.runBuild(BuildRunner.java:138)
at org.jetbrains.jps.cmdline.BuildSession.runBuild(BuildSession.java:297)
at org.jetbrains.jps.cmdline.BuildSession.run(BuildSession.java:130)
at org.jetbrains.jps.cmdline.BuildMain$MyMessageHandler.lambda$channelRead0$0(BuildMain.java:218)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Example code:
// Main.java
@Command(name = "main", subcommands = { Sub.class })
public class Main implements Runnable {
public void run() { }
public static void main(String[] args) {
CommandLine cmd = new CommandLine(new Main());
int exitCode = cmd.execute("add", "add", "list");
}
}
// Sub.java
@CommandLine.Command(name = "sub")
class Sub implements Runnable {
@ArgGroup(exclusive = true)
MyGroup myGroup;
public void run() { }
static class MyGroup {
@CommandLine.Option(names = "-x") String x;
@CommandLine.Option(names = "-y") String y;
}
}
@antonmry and @hatyo, I found the cause of the issue.
During incremental compilation, only the class that is modified is passed to the annotation processor.
The processor would find the classes of the subcommands, and process these (even if not passed by the IntelliJ compiler), but it would not make the same effort for the class of @ArgGroup annotated fields.
Fixing the processor to take that extra step, and also process the class of @ArgGroup annotated fields, allows the processor to discover all elements necessary to build the argument group correctly.
Thank you both again for raising this issue.
I will do a bugfix release that includes this fix soon.
Picocli 4.5 has been released, which includes this fix.
Most helpful comment
@antonmry and @hatyo, I found the cause of the issue.
During incremental compilation, only the class that is modified is passed to the annotation processor.
The processor would find the classes of the subcommands, and process these (even if not passed by the IntelliJ compiler), but it would not make the same effort for the class of
@ArgGroupannotated fields.Fixing the processor to take that extra step, and also process the class of
@ArgGroupannotated fields, allows the processor to discover all elements necessary to build the argument group correctly.Thank you both again for raising this issue.
I will do a bugfix release that includes this fix soon.