159 lines
5.2 KiB
Plaintext
159 lines
5.2 KiB
Plaintext
[[using-shell-building]]
|
|
= Building
|
|
|
|
This section covers how to build a Spring Shell application.
|
|
|
|
== Starters
|
|
|
|
. 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-ffm| With JLine ffm provider (requires JDK22+)
|
|
|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.
|
|
|
|
== FFM
|
|
|
|
With `JDK22` a _Foreign Function and Memory API_ came out from a preview
|
|
which is supposed to be a replacement for `JNI` providing much better
|
|
and safer native API.
|
|
|
|
Starting from `3.4.x` we've added a support to compile Spring Shell
|
|
application with `JLine` `ffm` terminal provider. This obviously mean
|
|
that application needs to be run with `JDK22+`. There is a new JDK
|
|
intermediate release every 6 months and long term support(LTS) release
|
|
every 2 years. Until there's an existing LTS release Spring Shell can
|
|
align with Spring Framework we will use latest JDK release. Obviously
|
|
this means that you may need to upgrade your JDK in an inconvenient
|
|
time if you choose to use `ffm`. We're also bound to JDK version
|
|
`JLine` itself uses to compile its `ffm` parts.
|
|
|
|
FFM itself will cause jvm to print warnings when some part of it are
|
|
used. These warnings are obviously annoying with terminal applications
|
|
as it may interfere and cause a little bit of a mess. In future JDK
|
|
versions these warnings will also be added for an older JNI modules and
|
|
at some point these warnings will be changed into hard errors. User will
|
|
be required to enable these native "unsafe" parts manually.
|
|
|
|
JVM option for this in a command line is:
|
|
|
|
[source, bash]
|
|
----
|
|
--enable-native-access=ALL-UNNAMED
|
|
----
|
|
|
|
If you have a jar file you can have this setting in its `META-INF/MANIFEST.MF`.
|
|
|
|
[source]
|
|
----
|
|
Enable-Native-Access: ALL-UNNAMED
|
|
----
|
|
|
|
Which can be added during a build i.e. if using gradle:
|
|
|
|
[source, groovy]
|
|
----
|
|
tasks.named("bootJar") {
|
|
manifest {
|
|
attributes 'Enable-Native-Access': 'ALL-UNNAMED'
|
|
}
|
|
}
|
|
----
|
|
|
|
IMPORTANT: What comes for enabling native parts in a JDK, JLine has been
|
|
proactive and already has a check for this and will throw error if
|
|
native access is not enabled.
|
|
|
|
[[native]]
|
|
== 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.
|
|
|
|
IMPORTANT: 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.
|
|
|
|
[source, groovy, subs=attributes+]
|
|
----
|
|
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:
|
|
|
|
[source, xml, subs=attributes+]
|
|
----
|
|
<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>
|
|
----
|
|
|
|
NOTE: 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.
|