Picocli | Create your first Kotlin /JVM CLI application with GraalVM

Setup Environment

The second step is to configure the build.gradle.kts file so that it looks like this: I’ll explain it later.

  1. You need to add the Kotlin plugin and kotlin.kapt.
  2. Add picocli-codegen as kapt (kotlin-annotation-processor)
  3. Add picocli as an implementation
  4. Create kapt block with the argument project.
  5. Configure the jar file output by setting a manifest with the attribute Main-Class. In my case it is CheckSumKt.
  6. Exclude the META-INF files from the classpath.
  7. Enable Annotation Processors in intelliJ. Docs here

Create the CheckSum class

The Class or command Checksum has a parameter and one option. With the Parameter annotation you can define, at which position the parameter should get read in. You could give it a default value, in my example, I leave it without.

With the Option annotation you can define options like the algorithm. You can also give it a default value. In this case “MD5”.

The next part is the call() function. It creates a ByteArray with the provided file. Then it converts that ByteArray to a checkSum of the chosen algorithm. After that it just prints out that cryptic value on a new line and returns 0.

The return value needs to be 0, because every other value would be a failure.

The last step is the main function. It Takes an Array of Strings as arguments and returns nothing. This main class creates an instance of the Checksum class and executes it. The logic for this is handeled by Picocli.

Build and start the Application

$ ./gradlew clean build

To start your application now, run:

$ java -jar build/libs/picocli-test-1.0.jar

picocli-test is the project name in my example. The version is defined in the build.gradle.kts file.

The output should look something like this. You can use these parameters and options defined in your CheckSum class. For example to see the SHA-1 checkSum of a file with the content “hello” you would type:

To run this jar file like a real cli application, run these two commands in your project directory.

echo "export PATH=$PATH:$(pwd)" >> ~/.zshrc
echo "alias checksumjar='java -jar $(pwd)/build/libs/picocli-test-1.0.jar'" >> ~/.zshrc

The first one adds the current directory to the PATH variable. This makes the files in this directory executable. The second one creates an alias for the jar file.

Native with GraalVM

$ brew install graalvm-ce-java8

Now you need to set the prerequesites for GraalVM like described here.

After that, you can go to the java home of the GraalVM and run ./bin/gu

$ cd /Library/Java/JavaVirtualMachines/graalvm-ce-java8-      21.0.0/Contents/Home$ ./bin/gu install -L /bin/native-image

The last step is to actually create the actual image with :

$ $GRAAL_HOME/native-image -cp classes:build/libs/picocli-test-1.0.jar --no-server  -H:Name=checksum CheckSumKt

The result you will endup is a file in the root of your project with the name checksum. You can run it with

$ ./checksum

Why GraalVM?

Speed difference:

The total time got minimized by a factor of 17 ! 🤯 Thats a big difference, especially if the application gets bigger.

Thanks for reading this article. I hope it was helpful

Developer Experience Engineer

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store