-
Notifications
You must be signed in to change notification settings - Fork 425
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 binding options and parameters without reflection #1003
Comments
Hi James, thanks for your question! Yes, this facility already exists in picocli's programmatic API, see the Programmatic API and Bindings part of my answer below, but I do wonder why you need it. Annotations and reflection in picocliThe example you gave uses annotations. When an application uses picocli's annotations framework, picocli uses reflection in multiple places:
You mention this last usage of reflection in picocli but be aware this is not the only usage for applications that use the annotations API. Current SolutionThe solution that picocli offers out of the box for creating native executables with GraalVM (as I am sure you are aware) is to generate a Future SolutionsI am considering a different approach for processing annotations, without reflection, in a future release of picocli. The basic idea would be to generate code at compile time; I believe this is similar to the approach Micronaut takes. Some early thoughts on this topic are in this ticket. This is at the conceptual stage and would require quite a bit of work to design, implement, test and document. Programmatic APIApplications can avoid reflection altogether by using picocli's programmatic API. This is a different programming model that does not use the annotations. BindingsAnd now we finally get to answer your question! :-) The programmatic API manual has a section on bindings, but in a nutshell: An option or positional parameter is represented in picocli with the Applications can provide custom IGetter and ISetter implementations, to get complete control over what happens when a value is matched. You would use it as follows: CommandSpec spec = CommandSpec.create();
spec.addPositional(PositionalParamSpec.builder()
.paramLabel("CONTROLLER-NAME")
.description("The name of the controller to create")
.getter(() -> { return getCreateControllerCommandInstance().controllerName; })
.setter((value) -> { getCreateControllerCommandInstance().controllerName = value; })
.type(String.class).auxiliaryTypes(String.class) // for type conversion
.build());
// assumes there is a getCreateControllerCommandInstance() method
// that returns your CreateControllerCommand instance This example uses If the By contrast, if the |
@jameskleeh Did this answer your question? |
@remkop Yes - I appreciate the detailed response! Going to consider the programmatic approach |
Ok, let me know if you run into any snags or have questions. The programmatic API docs are not as detailed as the main user manual; let me know if it is missing stuff. |
Wild idea: depending on how many commands and options your application has, it may be just as easy to generate the source code. Building such a code generator is on the picocli roadmap: see #539 (also related: #750). Picocli can already build a What is missing is to generate the source code (using the programmatic API) from this So, basically, given an annotated class: @CommandLine.Command(name = "create-controller", description = "Creates a controller and associated test")
public class CreateControllerCommand extends CodeGenCommand {
@CommandLine.Parameters(paramLabel = "CONTROLLER-NAME", description = "The name of the controller to create")
String controllerName; Generate something like this at compile time:
The Micronaut team may have more experience in this than me. Would you be interested in collaborating on #539? |
Currently something like the following requires special notation to work with GraalVM:
The controllerName field is bound via reflection. There should be a hook to allow for the user to control how the property is bound to avoid reflection.
The text was updated successfully, but these errors were encountered: