For the latest stable version, please use Spring Shell 4.0.1!

Building

This section covers how to build a Spring Shell application.

Starters

  1. Spring Shell Starters

Name Description

spring-shell-starter

Basic Spring Shell modules

spring-shell-starter-jansi

With JLine jansi provider

spring-shell-starter-jni

With JLine jni provider

spring-shell-starter-jna

With JLine jna provider

spring-shell-starter-test

Spring Shell testing support

Terminal Providers

Interacting with an underlying terminal where your program is running has traditionally been relatively complex process while it may look like there’s not that much happening as it’s all just text.

Remember all those old manual typewriters or matrix printers? A character is printed then a cursor needs to be moved if printing in a different position. In a nutshell that’s how current terminal emulators work.

To access and understand existing terminal emulators environment better, JLine can use native code via its own shared libraries. JLine detects which providers are present and then makes a choice which one to use. Traditionally there’s been 3 providers, jansi, jni and jna which should all provide same functionalities.

Our starters can be used to specifically pick some of these JLine providers.

Native Support

Support for compiling Spring Shell application into a GraalVM binary mostly comes from Spring Framework and Spring Boot where feature is called AOT. Ahead of Time means that application context is prepared during the compilation time to being ready for GraalVM generation.

Building atop of AOT features from a framework Spring Shell has its own GraalVM configuration providing hints what should exist in a binary. Usually trouble comes from a 3rd party libraries which doesn’t yet contain GraalVM related configurations or those configurations are incomplete.

It is requred to use GraalVM Reachability Metadata Repository which provides some missing hints for 3rd party libraries. Also you need to have GraalVM installed and JAVA_HOME pointing to that.

For gradle add graalvm’s native plugin and configure metadata repository.

plugins {
	id 'org.graalvm.buildtools.native' version '0.9.16'
}

graalvmNative {
	metadataRepository {
        enabled = true
	}
}

When gradle build is run with ./gradlew nativeCompile you should get binary under build/native/nativeCompile directory.

For maven use spring-boot-starter-parent as parent and you’ll get native profile which can be used to do a native compilation. You need to configure metadata repository:

<build>
    <pluginManagement>
        <plugins>
            <plugin>
                <groupId>org.graalvm.buildtools</groupId>
                <artifactId>native-maven-plugin</artifactId>
                <configuration>
                    <metadataRepository>
                        <enabled>true</enabled>
                    </metadataRepository>
                </configuration>
            </plugin>
        </plugins>
    </pluginManagement>
</build>
If you rely on spring-boot-starter-parent it manages native-maven-plugin version which is kept up to date.

When maven build is run with ./mvnw native:compile -Pnative you should get binary under target directory.

If everything went well this binary can be run as is instead of executing boot application jar via jvm.