跳到主要内容

构建

ChatGPT-4o-mini 中英对照 Building

本节介绍如何构建一个 Spring Shell 应用程序。

开始

  1. 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-testSpring Shell 测试支持

终端提供商

与程序运行的底层终端交互传统上是一个相对复杂的过程,尽管看起来似乎没有发生太多事情,因为这只是文本。

还记得那些旧的手动打字机或矩阵打印机吗?字符在光标所在的位置打印,如果需要在不同的位置打印,则需要移动光标。简而言之,这就是当前终端仿真器的工作原理。

为了更好地访问和理解现有的终端仿真器环境,JLine 可以通过其自己的共享库使用本地代码。JLine 检测哪些提供者存在,然后选择使用其中的一个。传统上,有 3 个提供者,jansijnijna,它们应该提供相同的功能。

我们的启动器可以用来专门选择这些 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
bash

如果你有一个 jar 文件,你可以在其 META-INF/MANIFEST.MF 中设置这个。

Enable-Native-Access: ALL-UNNAMED
none

可以在构建期间添加,即如果使用 gradle:

tasks.named("bootJar") {
manifest {
attributes 'Enable-Native-Access': 'ALL-UNNAMED'
}
}
groovy
important

在 JDK 中启用本地部分时,JLine 已经主动进行了检查,如果未启用本地访问,将会抛出错误。

原生支持

支持将 Spring Shell 应用程序编译为 GraalVM 二进制文件的主要来源是 Spring FrameworkSpring Boot,该功能称为 AOT。提前准备意味着应用程序上下文在编译时就已准备好,以便为 GraalVM 生成做好准备。

基于框架 Spring ShellAOT 特性构建的内容,具有自己的 GraalVM 配置,提供了有关二进制文件中应该存在什么的提示。通常问题来自于尚未包含 GraalVM 相关配置的第三方库,或者这些配置不完整。

important

必须使用 GraalVM Reachability Metadata Repository,它为第三方库提供了一些缺失的提示。此外,您需要安装 GraalVM 并将 JAVA_HOME 指向它。

对于 gradle,添加 graalvm 的本地插件并配置元数据存储库。

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

graalvmNative {
metadataRepository {
enabled = true
}
}
groovy

当运行 ./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>
xml
备注

如果您依赖于 spring-boot-starter-parent,它会管理 native-maven-plugin 的版本,并保持其更新。

当运行 maven 构建命令 ./mvnw native:compile -Pnative 时,您应该在 target 目录下获得二进制文件。

如果一切顺利,这个二进制文件可以直接运行,而无需通过 jvm 执行启动应用程序 jar。