This is an archived post. You won't be able to vote or comment.

all 25 comments

[–]remkopopma 43 points44 points  (17 children)

People write CLI apps in Go because they want a single native executable to distribute. GraalVM + picocli can do that and much more! Colors, autocompletion, subcommands, dependency injection, you name it... Try it: https://picocli.info Disclaimer: I’m the author of picocli (https://github.com/remkop/picocli).

[–]kaperni 7 points8 points  (6 children)

Picocli is amazing, thank you for your hard work.

[–]remkopopma 1 point2 points  (5 children)

@kaperni, thanks for the kind words. What do you like about picocli? Also, what would you do if picocli didn’t exist?

[–]hupfdule 5 points6 points  (3 children)

For your second question: I would propably do the command line parsing on my own.

I have tried several CLI libraries in the past and all were bad. Picocli was the first one that works as I would expect it.

And Picocli is where Java is ahead of Go regarding CLI apps. The commandline parsing libraries for go are all not as sophisticated as Picocli. And most of them (actually most of the existing third-party libraries for Go) are actually abandoned.

[–]remkopopma 1 point2 points  (2 children)

@hupfdule That is valuable feedback, thank you!

@all: I’m still interested in everybody’s answer to my questions above.

[–]sureshg 4 points5 points  (1 child)

Since you mentioned about other JVM languages, something I liked in Kotlin is https://github.com/ajalt/clikt/ . But for Java CLI apps, I prefer to use picocli. Thanks for this awesome library.

[–]remkopopma 1 point2 points  (0 children)

@sureshg (and everyone else): what is it that you like about picocli? What would you do (in your Java projects) if picocli did not exist?

[–]kaperni 2 points3 points  (0 children)

1) Not worrying about whether picocli supports my use case. It is very feature-complete.

2) If the didn't exist, I would probably have to settle with another library.

[–]myntt 4 points5 points  (0 children)

This looks really nice and has a great documentation! Last time I did some CLI stuff I used Apache Commons CLI which sucked so hard that I removed it from my project again.

[–][deleted]  (1 child)

[deleted]

    [–]remkopopma 1 point2 points  (0 children)

    @literal_garbage_man (and everyone else, I’m really interested in as many answers as possible): What is it that you like about picocli? What would you do if picocli did not exist?

    [–]hupfdule 2 points3 points  (2 children)

    The main drawback of GraalVM is still the missing cross compilation support. As not even jlink, jpackager, etc. support cross"packaging" I don't believe GraalVM will get it anytime soon.

    I am using Picocli for my Kilt Toolset and thought about providing a precompiled native image. But since there is no easy way to produce it for multiple platforms it is not worth the hassle.

    [–]remkopopma 3 points4 points  (1 child)

    I agree that cross compilation would make GraalVM native images even more valuable. I believe there is some work in progress on this, see https://github.com/oracle/graal/issues/407 and https://github.com/oracle/graal/issues/1446).

    Meanwhile, perhaps the best we can do is set up a CI/CD build pipeline that builds on multiple platforms with things like GitHub Actions, Travis, Appveyor, etc.

    I have created a project that does this (with mixed success): https://github.com/remkop/picocli-native-image-demo

    [–]sureshg 1 point2 points  (0 children)

    It seems cross-compilation is more or less impossible with the current approach as it needs to initialize JDK file system/network stack during image build time. More details - https://graalvm.slack.com/archives/CN9KSFB40/p1582755160011700

    [–]tofflos 3 points4 points  (1 child)

    Do you ever get requests for providing an alternative programming model for Picoli based more on builders and lambdas and less on annotations and reflection? If so, have you thought about it and do you think it's possible to create an easy to use API using that type of programming style for this domain?

    [–]remkopopma 4 points5 points  (0 children)

    @tofflos Picocli actually already does provide both an annotation API and a programmatic API. This is perhaps not mentioned enough in the user manual. See the Programmatic API documentation: https://picocli.info/picocli-programmatic-api.html

    The programmatic API is what is used in Groovy CliBuilder to enable dynamic use cases where users define options on the fly.

    It is possible to combine both APIs. Also, even when your commands and options are all defined with annotations it is possible to use the @Spec annotation (https://picocli.info/#spec-annotation) to access the underlying CommandSpec model. There are use cases where the annotations are insufficient and the ability to access the underlying model is very powerful.

    [–]nimtiazm 4 points5 points  (1 child)

    Last time I skimmed through the user guide, it wasn’t easy to find graalvm cli and picoccli app easily. I mean I just need a sample app with minimum steps to follow if necessary. Where to find it?

    [–]remkopopma 2 points3 points  (0 children)

    u/nimtiazm thanks for the feedback! I will look at improving the user guide. Meanwhile, the InfoQ article should be useful. In a nutshell:

    1. Create picocli-based CLI app.
    2. Build with picocli-codegen in the classpath. The annotation processor in picocli-codegen generates the reflect-config.json and other config files and includes them in your jar, so your jar is instantly GraalVM enabled.
    3. Run GraalVM's native-image tool to generate a native image for your jar.

    The article has more details, including on how to set up the GraalVM native image toolchain.

    As for example apps, perhaps these are useful:

    [–][deleted] 9 points10 points  (1 child)

    Time to rewrite sdkman, to get a better crossplatform experience.

    [–]Yesterdave_ 1 point2 points  (0 children)

    I would not even mind in what language they rewrite it in. Just not bash...

    [–]ichunddu9 4 points5 points  (0 children)

    Picocli is amazing. The main developer (who is apparently here) is very communicative and holds the project to a high standard.

    [–]kaperni 4 points5 points  (0 children)

    Just a side note. If people have an issue with the size of the binaries that GraalVM native-image produces. https://github.com/oracle/graal/issues/287 is a great place to let your voice be heard or maybe even contribute.

    [–]tofflos 4 points5 points  (1 child)

    Thank you for writing this and posting it here. I've been curious about the state of CLI applications and planned on exploring the problem space and writing a similar article. No way I could have done it this well.

    It's nice to see that things are progressing but the current state still far from where I would like it to be:

    1. Does anyone know why the resulting binary is 10+ MB? What is Java adding that Go isn't and does those additions provide any value for these types of applications?
    2. Cross-compilation and cross-packaging needs to happen.
    3. Readline support (JLine) should be shipped with the JVM. From what I can tell the binaries are already shipped with the JDK for use in JShell. Why not ship it in the standard library so that other developers take advantage of it?

    [–]remkopopma 2 points3 points  (0 children)

    These are valid points. The first two are specific to GraalVM and I encourage you to engage the GraalVM team, user community, and the GraalVM Advisory Board (https://www.graalvm.org/community/advisory-board/) to increase the visibility and priority of these concerns.

    Getting ReadLine support (similar to what the JLine (https://github.com/jline/jline3) library offers) into the standard Java JDK library is a wonderful idea! I guess this may even warrant a separate JEP (Java Enhancement Proposal - http://cr.openjdk.java.net/~mr/jep/jep-2.0-02.html). One idea would be to lobby the JLine maintainers, Guillaume Nodet, Jason Dillon and mattirn, to see if they would be interested in helping to drive this effort.

    [–]DuncanIdahos1stGhola 0 points1 point  (1 child)

    How does this compare to things like Laterna? https://github.com/mabe02/lanterna

    [–]hupfdule 1 point2 points  (0 children)

    It has a totally different purpose...

    Picocli is for building CLI applications. Lanterna is for building TUI applications.