This is a template repository for building CLI applications with Java. It leverages Picocli for bootstrapping the CLI execution and GraalVM native-image for building a native image executable.
- JDK Version:
17 - GraalVM Version:
21.3.0
For the native-image build, see instructions at bottom for tooling pre-requisites. Your
JAVA_HOME will need to be set with GraalVM installation.
./mvnw clean install # Build executable JAR
./mvnw clean install -D nativeImage # Build native image./gradlew clean build # Build executable JAR
./gradlew clean nativeImage # Build native imageAn external build is first required since the Dockerfile needs to ADD the executable JAR.
By default, the JAR used is from maven build.
docker build -t java-cli-template .To use the gradle build output:
docker build -t java-cli-template --build-arg "JAR=build/libs/java-cli-template-*.jar" .java -jar target/java-cli-template-*.jar --help
java -jar target/java-cli-template-*.jar hello-world
java -jar target/java-cli-template-*.jar hello-world Brian
echo "Brian" | java -jar target/java-cli-template-*.jar hello-world -./target/app --help
./target/app hello-world
./target/app hello-world Brian
echo "Brian" | ./target/app hello-world -java -jar build/libs/java-cli-template-*.jar --help
java -jar build/libs/java-cli-template-*.jar hello-world
java -jar build/libs/java-cli-template-*.jar hello-world Brian
echo "Brian" | java -jar build/libs/java-cli-template-*.jar hello-world -./build/graal/app --help
./build/graal/app hello-world
./build/graal/app hello-world Brian
echo "Brian" | ./build/graal/app hello-world -docker run java-cli-template --help
docker run java-cli-template hello-world
docker run java-cli-template hello-world Brian
echo "Brian" | docker run -i java-cli-template hello-world -Runtime reflection in a native image is tricky. GraalVM can detect basic usage of class loading with reflection, however it cannot determine classes loaded dynamically. To allow it to work, some configuration needs to be done.
See Reflect.java for how the class is loaded "dynamically".
./app reflect java.lang.StringThis is because it has been configured in reflect-config.json.
./app reflect java.util.ListThis is because it is not included in reflect-config.json
The maven build requires that GraalVM and native-image tooling already be available on the machine.
- GraalVM CE
- GraalVM CE
native-image zlib/xcode
./install-graalvm.shIf you are using Gradle or Docker, you do not need to perform this installation.