-
Notifications
You must be signed in to change notification settings - Fork 420
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
"Duplicate annotation for class" with @PicocliScript when the script contains classes #388
Comments
Thank you for the bug report! With the inner class, the decompiled code for the script looks like this: import org.codehaus.groovy.runtime.GStringImpl;
import org.codehaus.groovy.runtime.InvokerHelper;
import org.codehaus.groovy.runtime.callsite.CallSite;
import picocli.CommandLine.Command;
import picocli.CommandLine.Option;
@Command(
name = "classyTest",
mixinStandardHelpOptions = true,
separator = " ",
version = {"0.1"}
)
@Command(
name = "classyTest",
mixinStandardHelpOptions = true,
separator = " ",
version = {"0.1"}
)
public class ScriptWithInnerClassTest extends PicocliBaseScript {
@Option(
names = {"-g", "--greeting"},
description = {"Type of greeting"}
)
String greeting;
public ScriptWithInnerClassTest() {
CallSite[] var1 = $getCallSiteArray();
String var2 = "Hello";
this.greeting = var2;
}
public static void main(String... args) {
CallSite[] var1 = $getCallSiteArray();
var1[0].call(InvokerHelper.class, ScriptWithInnerClassTest.class, args);
}
protected Object runScriptBody() {
CallSite[] var1 = $getCallSiteArray();
Object var10000 = null;
return var1[1].callCurrent(this, new GStringImpl(new Object[]{this.greeting}, new String[]{"", " world!"}));
}
} While the decompiled inner class looks like this: import groovy.lang.GroovyObject;
import groovy.lang.MetaClass;
import org.codehaus.groovy.runtime.callsite.CallSite;
public class Message implements GroovyObject {
private String greeting;
private String target;
public Message() {
CallSite[] var1 = $getCallSiteArray();
MetaClass var2 = this.$getStaticMetaClass();
this.metaClass = var2;
}
public String getGreeting() {
return this.greeting;
}
public void setGreeting(String var1) {
this.greeting = var1;
}
public String getTarget() {
return this.target;
}
public void setTarget(String var1) {
this.target = var1;
}
} Still investigating... |
It turns out that the AST transformation is invoked twice if the script contains an inner class. (I didn't experiment further if it would be invoked more often for additional inner classes.) The fix is to only add the annotation if it does not already exist.
This test breaks without the fix but passes when the fix is applied:
|
I will release a new version with this fix within the next day or two. |
I just released picocli 3.1, which includes the fix for this issue. Thanks again for the bug report! Keep them coming! |
Thanks, that was turbo-fast! |
Spread the word! |
This works as expected:
However, if the
Message
class is un-commented, I get the following error:I guess maybe the AST transformation is somehow being applied to the "inner" class as well?
The script will also run if the
Message
part is un-commented, but with the@Command
line removed. But then I don't think there is a way to specify things likeseparator
andmixinStandardHelpOptions
. Is there someway to make sure the@Command
annotation is applied just to the Script class itself, and not other classes within?The text was updated successfully, but these errors were encountered: