构建
本节介绍如何构建一个 Spring Shell 应用程序。
开始
- Spring Shell 启动器
名称 | 描述 |
---|---|
spring-shell-starter | 基本的 Spring Shell 模块 |
spring-shell-starter-jansi | 带有 JLine jansi 提供者 |
spring-shell-starter-jni | 带有 JLine jni 提供者 |
spring-shell-starter-jna | 带有 JLine jna 提供者 |
spring-shell-starter-ffm | 带有 JLine ffm 提供者(需要 JDK22+) |
spring-shell-starter-test | Spring Shell 测试支持 |
终端提供商
与程序运行的底层终端交互传统上是一个相对复杂的过程,尽管看起来似乎没有发生太多事情,因为这只是文本。
还记得那些旧的手动打字机或矩阵打印机吗?字符在光标所在的位置打印,如果需要在不同的位置打印,则需要移动光标。简而言之,这就是当前终端仿真器的工作原理。
为了更好地访问和理解现有的终端仿真器环境,JLine 可以通过其自己的共享库使用本地代码。JLine 检测哪些提供者存在,然后选择使用其中的一个。传统上,有 3 个提供者,jansi
、jni
和 jna
,它们应该提供相同的功能。
我们的启动器可以用来专门选择这些 JLine 提供者中的一些。
FFM
随着 JDK22
的发布,一个 外部函数和内存 API 从预览版中推出,旨在替代 JNI
,提供更好和更安全的本地 API。
从 3.4.x
开始,我们增加了对使用 JLine
ffm
终端提供程序编译 Spring Shell 应用程序的支持。这显然意味着应用程序需要在 JDK22+
上运行。每 6 个月会有一个新的 JDK 中间版本,每 2 年会有一个长期支持(LTS)版本。在现有的 LTS 版本与 Spring Framework 对齐之前,我们将使用最新的 JDK 版本。显然,这意味着如果您选择使用 ffm
,您可能需要在不方便的时间升级您的 JDK。我们也受限于 JLine
自身用于编译其 ffm
部分的 JDK 版本。
FFM 本身会导致 jvm 在使用其某些部分时打印警告。这些警告在终端应用程序中显然是令人烦恼的,因为它们可能会干扰并造成一些混乱。在未来的 JDK 版本中,这些警告也将被添加到较旧的 JNI 模块中,并且在某些时候,这些警告将被更改为硬错误。用户将被要求手动启用这些本地的 "不安全" 部分。
命令行中对此的 JVM 选项是:
--enable-native-access=ALL-UNNAMED
如果你有一个 jar 文件,你可以在其 META-INF/MANIFEST.MF
中设置这个。
Enable-Native-Access: ALL-UNNAMED
可以在构建期间添加,即如果使用 gradle:
tasks.named("bootJar") {
manifest {
attributes 'Enable-Native-Access': 'ALL-UNNAMED'
}
}
在 JDK 中启用本地部分时,JLine 已经主动进行了检查,如果未启用本地访问,将会抛出错误。
原生支持
支持将 Spring Shell 应用程序编译为 GraalVM 二进制文件的主要来源是 Spring Framework 和 Spring Boot,该功能称为 AOT。提前准备意味着应用程序上下文在编译时就已准备好,以便为 GraalVM 生成做好准备。
基于框架 Spring Shell 的 AOT 特性构建的内容,具有自己的 GraalVM 配置,提供了有关二进制文件中应该存在什么的提示。通常问题来自于尚未包含 GraalVM 相关配置的第三方库,或者这些配置不完整。
必须使用 GraalVM Reachability Metadata Repository,它为第三方库提供了一些缺失的提示。此外,您需要安装 GraalVM 并将 JAVA_HOME
指向它。
对于 gradle,添加 graalvm 的本地插件并配置元数据存储库。
plugins {
id 'org.graalvm.buildtools.native' version '0.9.16'
}
graalvmNative {
metadataRepository {
enabled = true
}
}
当运行 ./gradlew nativeCompile
进行 gradle 构建时,您应该在 build/native/nativeCompile
目录下获得二进制文件。
对于 maven
,使用 spring-boot-starter-parent
作为父项目,你将获得 native
配置文件,可以用于编译。你需要配置元数据存储库。
<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>
如果您依赖于 spring-boot-starter-parent
,它会管理 native-maven-plugin
的版本,并保持其更新。
当运行 maven 构建命令 ./mvnw native:compile -Pnative
时,您应该在 target
目录下获得二进制文件。
如果一切顺利,这个二进制文件可以直接运行,而无需通过 jvm 执行启动应用程序 jar。