Skip to content
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

Support generating autocompletion scripts for non-public @Command classes #306

Closed
cbeams opened this issue Mar 23, 2018 · 4 comments
Closed

Comments

@cbeams
Copy link

cbeams commented Mar 23, 2018

Problem

When following the instructions at http://picocli.info/autocomplete.html to generate a bash completion script for a non-public @Command class, picocli.AutoComplete throws the following exception:

java.lang.IllegalAccessException: Class picocli.AutoComplete$App can not access a member of class bisq.cli.Bisq with modifiers ""
        at sun.reflect.Reflection.ensureMemberAccess(Reflection.java:102)
        at java.lang.Class.newInstance(Class.java:436)
        at picocli.AutoComplete$App.run(AutoComplete.java:89)
        at picocli.CommandLine.execute(CommandLine.java:775)
        at picocli.CommandLine.access$700(CommandLine.java:139)
        at picocli.CommandLine$RunLast.handle(CommandLine.java:998)
        at picocli.CommandLine$RunLast.handle(CommandLine.java:966)
        at picocli.CommandLine$AbstractParseResultHandler.handleParseResult(CommandLine.java:831)
        at picocli.CommandLine.parseWithHandlers(CommandLine.java:1182)
        at picocli.CommandLine.run(CommandLine.java:1544)
        at picocli.CommandLine.run(CommandLine.java:1494)
        at picocli.AutoComplete.main(AutoComplete.java:51)

This is because (a) bisq.cli.Bisq is declared (intentionally) with package-private visibility, and (b) because picocli.AutoComplete$App.run attempts to reflectively instantiate it using Class.newInstance(), which respects declared visibility modifiers and provides no option to override them.

Solution

Instead of Class.newInstance(), first get the class's no-arg Constructor with Class.getConstructor(), then call setAccessible(true) on it followed by newInstance. This will allow users to keep declaring their @Command classes with whatever visibility they see fit.

@remkop
Copy link
Owner

remkop commented Mar 23, 2018

Understood. I will look into this. Can you please provide a failing JUnit test so I can reproduce the issue and be confident that my changes fix the issue.

If you want to go ahead and provide a pull request with a fix that’d be even better!

@remkop remkop closed this as completed in fbfaf6e Mar 25, 2018
@remkop
Copy link
Owner

remkop commented Mar 25, 2018

Fixed in master. Please try and let me know if this fixed the issue.

@cbeams
Copy link
Author

cbeams commented Mar 28, 2018

@remkop, I've tried this out against 3.0.0-alpha-2 and everything works as expected. Thanks!

@remkop
Copy link
Owner

remkop commented Mar 28, 2018

Perfect!

cbeams added a commit to cbeams/bisq-core that referenced this issue Jun 29, 2018
To pick up the changes described in remkop/picocli#306 that allow for
generating bash completion scripts for package-private @command classes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants