Ubuntu 22.04 安装 Apache BVal 指南

在 Ubuntu 22.04 从零安装 Apache BVal 3.0.2:JDK 17 与 Maven 安装、Maven 依赖与手动双 jar 两方案、sha1 校验、最小验证代码与多版本管理,命令与回显全部实测。

Apache BValBVal2026/10/13

Ubuntu 22.04 安装 Apache BVal 指南

目标:在 Ubuntu 22.04 服务器上从零搭建可编译、可运行 Apache BVal(Jakarta Bean Validation 实现)的 Java 环境,覆盖「Maven 依赖」与「Maven Central 手动双 jar」两种方案、sha1 完整性校验、最小验证代码、多版本管理与卸载,已在 Ubuntu 22.04(OpenJDK 17.0.20.1、Maven 3.6.3)实测通过。

一、环境信息

本篇所有命令与回显均在以下环境中实测采集,复现时请保持相近版本:

  • 操作系统:Ubuntu 22.04(jammy),x86_64
  • JDK:OpenJDK 17.0.20.1(openjdk-17-jdk-headless,apt 官方仓库)
  • 构建工具:Apache Maven 3.6.3(maven,apt 官方仓库)
  • 组件版本:Apache BVal 3.0.2(org.apache.bval:bval-jsr,Maven 中央仓库当前最新稳定版,2026-10 实测)
  • 校验工具:coreutils sha1sum(Maven Central 为 BVal 提供 .sha1 校验文件)
  • 实验目录:/opt/bval-demo(方案 A 工程)与 /opt/bval-manual(方案 B 目录)
  • 执行用户:root

二、前置条件

本节确认系统版本、网络可达性与基础工具,保证后续下载与依赖解析能顺利完成。

2.1 确认系统与网络

cat /etc/os-release | head -2

回显(实测):

PRETTY_NAME="Ubuntu 22.04.5 LTS"
NAME="Ubuntu"
uname -m

回显(实测):

x86_64
curl -sI https://repo1.maven.org/maven2/org/apache/bval/bval-jsr/3.0.2/bval-jsr-3.0.2.jar | head -2

回显(实测):

HTTP/2 200
content-length: 748810

Maven Central 可达且目标 jar 存在(748810 字节),可以继续安装。BVal 的二进制 jar 官方渠道就是 Maven Central——官方下载站 downloads.apache.org/bval/ 只提供源码发行包(实测最新为 2.0.6 的 source-release.zip,3.0.2 无独立二进制包),这一点与自带 bin tarball 的 Commons 类项目不同。

2.2 安装基础工具

apt-get update -qq

回显(实测,-qq 静默模式成功无输出):

DEBIAN_FRONTEND=noninteractive apt-get install -y curl wget

输出节选(实测尾部):

Setting up libcurl4:amd64 (7.81.0-1ubuntu1.29) ...
Setting up curl (7.81.0-1ubuntu1.29) ...
Processing triggers for libc-bin (2.35-0ubuntu3.15) ...

apt 完成 curl 与 wget 的安装(本机基础镜像未预装,全新安装即如上;已预装的机器会以 0 upgraded, 0 newly installed 收尾)。验证工具就位:

wget --version | head -1

回显(实测):

GNU Wget 1.21.2 built on linux-gnu.

wget 版本号正常输出,5.1 节手动下载所需的下载工具就绪。

三、版本选型说明

BVal 是纯 Java 库,没有独立进程,选型核心是「库版本 + 命名空间(javax/jakarta)+ JDK 版本」匹配。先实测中央仓库当前版本序列:

curl -s 'https://search.maven.org/solrsearch/select?q=g:org.apache.bval%20AND%20a:bval-jsr&rows=5&wt=json&core=gav' | grep -oE '"v":"[^"]+"' | head -5

回显(实测):

"v":"3.0.2"
"v":"3.0.1"
"v":"3.0.0"
"v":"2.0.6"
"v":"2.0.5"

版本与命名空间对照如下(均为实测结论,依据见 4.4/5.4 节):

组件版本验证 APIJDK 要求获取渠道说明
BVal (bval-jsr)3.0.2jakarta.validation:jakarta.validation-api(3.0.x)Java 11+Maven 中央仓库本文采用,最新稳定版
BVal (bval-jsr)2.0.6javax.validation:validation-api(2.0.1.Final)Java 8+Maven 中央仓库存量 javax 工程用
JDKOpenJDK 17.0.20.1——Ubuntu apt 仓库运行与编译均正常
Maven3.6.3—Java 8+Ubuntu apt 仓库方案 A 依赖解析使用

关键差异与选型建议:3.0.x 与 2.0.x 的分水岭是 jakarta/javax 命名空间(SPI 注册文件名与 API 包名都不同,不互通);新工程直接用 3.0.2 并引入 jakarta.validation-api,老工程保持 2.0.6 + validation-api。本篇以 3.0.2 为准。

四、安装方案 A:Maven 依赖安装(在线,推荐)

4.1 安装 JDK 17 与 Maven

DEBIAN_FRONTEND=noninteractive apt-get install -y openjdk-17-jdk-headless maven

输出节选(实测首尾):

Reading package lists...
Building dependency tree...
Setting up maven (3.6.3-5) ...
Setting up openjdk-17-jdk-headless:amd64 (17.0.20.1+1-1~22.04) ...

分别验证:

java -version

回显(实测):

openjdk version "17.0.20.1" 2026-08-18
OpenJDK Runtime Environment (build 17.0.20.1+1-1-22.04-Ubuntu)
OpenJDK 64-Bit Server VM (build 17.0.20.1+1-1-22.04-Ubuntu, mixed mode, sharing)
mvn -version

回显(实测):

Apache Maven 3.6.3
Maven home: /usr/share/maven
Java version: 17.0.20.1, vendor: Ubuntu, runtime: /usr/lib/jvm/java-17-openjdk-amd64
Default locale: en_US, platform encoding: ANSI_X3.4-1968
OS name: "linux", version: "6.8.0-138-generic", arch: "amd64", family: "unix"

apt 安装的 Maven 自动绑定同仓库的 JDK 17,无需额外设置(对比 CentOS 8 需要手动切 JAVA_HOME)。注意 platform encoding: ANSI_X3.4-1968,中文输出乱码问题在第八节 FAQ Q2 处理。

4.2 创建工程与 pom.xml

mkdir -p /opt/bval-demo/src/main/java/demo

回显(实测,无输出即成功):

cat > /opt/bval-demo/pom.xml <<'EOF'
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>demo</groupId>
  <artifactId>bval-demo</artifactId>
  <version>1.0.0</version>
  <packaging>jar</packaging>
  <properties>
    <maven.compiler.source>17</maven.compiler.source>
    <maven.compiler.target>17</maven.compiler.target>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>
  <dependencies>
    <dependency>
      <groupId>org.apache.bval</groupId>
      <artifactId>bval-jsr</artifactId>
      <version>3.0.2</version>
    </dependency>
    <dependency>
      <groupId>org.apache.bval</groupId>
      <artifactId>bval-extras</artifactId>
      <version>3.0.2</version>
    </dependency>
    <dependency>
      <groupId>jakarta.validation</groupId>
      <artifactId>jakarta.validation-api</artifactId>
      <version>3.0.2</version>
    </dependency>
  </dependencies>
</project>
EOF

回显(实测,无输出即成功):

pom 逐项说明:maven.compiler.source/target 设 17 与 JDK 对齐(BVal 3.0.2 自身字节码为 Java 11,运行底线更低);project.build.sourceEncoding=UTF-8 保证中文字符串按 UTF-8 编译。三个依赖:bval-jsr 是校验实现本体,bval-extras 是扩展约束库(银行卡号/IBAN/IP/ISBN 等校验位算法),jakarta.validation-api 是 Jakarta Bean Validation 3.0 规范 API——bval-jsr 的 POM 把它声明为 provided(预期由容器提供),独立应用必须显式引入,否则编译不过。

4.3 编译并解析依赖

首次编译触发依赖下载:

cd /opt/bval-demo && mvn compile

输出节选(实测首尾):

[INFO] ---------------------------< demo:bval-demo >---------------------------
[INFO] Building bval-demo 1.0.0
[INFO] --------------------------------[ jar ]---------------------------------
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ bval-demo ---
[INFO] Compiling 1 source file to /opt/bval-demo/target/classes
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------

核对 jar 已落入本地仓库:

ls /root/.m2/repository/org/apache/bval/bval-jsr/3.0.2/ /root/.m2/repository/org/apache/bval/bval-extras/3.0.2/

回显(实测):

/root/.m2/repository/org/apache/bval/bval-extras/3.0.2/:
bval-extras-3.0.2.jar  bval-extras-3.0.2.pom  _remote.repositories

/root/.m2/repository/org/apache/bval/bval-jsr/3.0.2/:
bval-jsr-3.0.2.jar  bval-jsr-3.0.2.pom  _remote.repositories

BUILD SUCCESS 加本地仓库出现 bval 双 jar,依赖解析完成。

4.4 依赖树与最小运行 classpath

cd /opt/bval-demo && mvn dependency:tree -DoutputFile=/tmp/tree.txt >/dev/null 2>&1; cat /tmp/tree.txt

回显(实测):

demo:bval-demo:jar:1.0.0
+- org.apache.bval:bval-jsr:jar:3.0.2:compile
+- org.apache.bval:bval-extras:jar:3.0.2:compile
\- jakarta.validation:jakarta.validation-api:jar:3.0.2:compile

compile 范围只有这三个 jar。实测进一步确认:bval-jsr 的 POM 中 commons-lang3、jakarta.activation-api 等其余依赖均为 provided/optional,基础校验路径不触发它们——运行期最小 classpath 只需 bval-jsr + jakarta.validation-api 双 jar(bval-extras 仅在使用其扩展约束时需要)。

4.5 最小验证代码

cat > /opt/bval-demo/src/main/java/demo/BvalDemo.java <<'EOF'
package demo;

import jakarta.validation.Validation;
import jakarta.validation.Validator;
import jakarta.validation.ValidatorFactory;
import jakarta.validation.ConstraintViolation;
import jakarta.validation.constraints.*;
import java.util.Set;

public class BvalDemo {
    public static class User {
        @NotNull(message = "用户名不能为空")
        @Size(min = 3, max = 20, message = "用户名长度须在 {min}-{max} 之间")
        private String username;

        @NotBlank(message = "邮箱不能为空")
        @Email(message = "邮箱格式不合法")
        private String email;

        @Min(value = 18, message = "年龄不能小于 {value}")
        @Max(value = 120, message = "年龄不能大于 {value}")
        private Integer age;

        @Pattern(regexp = "1[3-9]\\d{9}", message = "手机号格式不合法")
        private String phone;

        public User(String username, String email, Integer age, String phone) {
            this.username = username; this.email = email; this.age = age; this.phone = phone;
        }
        public String getUsername() { return username; }
        public String getEmail() { return email; }
        public Integer getAge() { return age; }
        public String getPhone() { return phone; }
    }

    public static void main(String[] args) {
        ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
        Validator validator = factory.getValidator();
        System.out.println("ValidatorFactory 实现类: " + factory.getClass().getName());

        User bad = new User("ab", "not-an-email", 15, "12345");
        Set<ConstraintViolation<User>> violations = validator.validate(bad);
        System.out.println("非法对象约束违反数: " + violations.size());
        for (ConstraintViolation<User> v : violations) {
            System.out.println("  [" + v.getPropertyPath() + "] " + v.getMessage()
                    + " | 无效值 = " + v.getInvalidValue());
        }

        User good = new User("zhangsan", "zhangsan@example.com", 30, "13800138000");
        System.out.println("合法对象约束违反数: " + validator.validate(good).size());

        factory.close();
    }
}
EOF

回显(实测,无输出即成功):

用 Maven 编译并以 exec 插件运行(编码问题见 FAQ Q2,回显在 LANG=C.UTF-8 与 -Dfile.encoding=UTF-8 下采集):

cd /opt/bval-demo && LANG=C.UTF-8 JAVA_TOOL_OPTIONS=-Dfile.encoding=UTF-8 mvn -q compile exec:java -Dexec.mainClass=demo.BvalDemo 2>/dev/null

回显(实测):

ValidatorFactory 实现类: org.apache.bval.jsr.ApacheValidatorFactory
非法对象约束违反数: 4
  [email] 邮箱格式不合法 | 无效值 = not-an-email
  [username] 用户名长度须在 3-20 之间 | 无效值 = ab
  [age] 年龄不能小于 18 | 无效值 = 15
  [phone] 手机号格式不合法 | 无效值 = 12345
合法对象约束违反数: 0

要点:无需手写 SPI 注册文件,bval-jsr jar 自带 META-INF/services/jakarta.validation.spi.ValidationProvider(内容为 org.apache.bval.jsr.ApacheValidationProvider),buildDefaultValidatorFactory() 自动发现;四条违反逐一命中,消息模板 {min}-{max}/{value} 插值正确;validate() 返回 Set,条目顺序不固定属正常。

再用最小双 jar classpath 直跑,验证 4.4 节结论:

cd /opt/bval-demo && LANG=C.UTF-8 java -Dfile.encoding=UTF-8 -cp "target/classes:/root/.m2/repository/org/apache/bval/bval-jsr/3.0.2/bval-jsr-3.0.2.jar:/root/.m2/repository/jakarta/validation/jakarta.validation-api/3.0.2/jakarta.validation-api-3.0.2.jar" demo.BvalDemo | head -2

回显(实测首行):

ValidatorFactory 实现类: org.apache.bval.jsr.ApacheValidatorFactory
非法对象约束违反数: 4

双 jar 运行成功,方案 A 验证闭环完成。

五、安装方案 B:Maven Central 手动 jar 安装(不依赖构建工具)

5.1 下载双 jar 与校验文件

mkdir -p /opt/bval-manual/lib && cd /opt/bval-manual/lib && wget -q https://repo1.maven.org/maven2/org/apache/bval/bval-jsr/3.0.2/bval-jsr-3.0.2.jar -O bval-jsr-3.0.2.jar && wget -q https://repo1.maven.org/maven2/org/apache/bval/bval-jsr/3.0.2/bval-jsr-3.0.2.jar.sha1 -O bval-jsr-3.0.2.jar.sha1 && wget -q https://repo1.maven.org/maven2/jakarta/validation/jakarta.validation-api/3.0.2/jakarta.validation-api-3.0.2.jar -O jakarta.validation-api-3.0.2.jar && wget -q https://repo1.maven.org/maven2/jakarta/validation/jakarta.validation-api/3.0.2/jakarta.validation-api-3.0.2.jar.sha1 -O jakarta.validation-api-3.0.2.jar.sha1 && ls -l

回显(实测):

total 832
-rw-r--r-- 1 root root  93298 Oct 13 07:32 jakarta.validation-api-3.0.2.jar
-rw-r--r-- 1 root root     41 Oct 13 07:32 jakarta.validation-api-3.0.2.jar.sha1
-rw-r--r-- 1 root root 748810 Oct 13 07:32 bval-jsr-3.0.2.jar
-rw-r--r-- 1 root root     41 Oct 13 07:32 bval-jsr-3.0.2.jar.sha1

5.2 sha1 完整性校验

cd /opt/bval-manual/lib && cat bval-jsr-3.0.2.jar.sha1

回显(实测):

111d95c4f7c52f2a54dcb65bb0843e0026979ae6

Central 的 .sha1 是裸哈希(不含文件名),直接 sha1sum -c 会失败(实测,.sha512 则不存在、请求 404):

cd /opt/bval-manual/lib && sha1sum -c bval-jsr-3.0.2.jar.sha1; echo "exit=$?"

回显(实测):

sha1sum: bval-jsr-3.0.2.jar.sha1: no properly formatted SHA1 checksum lines found
exit=1

正确做法:拼出「哈希 + 文件名」标准行再校验:

cd /opt/bval-manual/lib && printf '%s  %s\n' "$(cat bval-jsr-3.0.2.jar.sha1)" bval-jsr-3.0.2.jar | sha1sum -c - && printf '%s  %s\n' "$(cat jakarta.validation-api-3.0.2.jar.sha1)" jakarta.validation-api-3.0.2.jar | sha1sum -c -

回显(实测):

bval-jsr-3.0.2.jar: OK
jakarta.validation-api-3.0.2.jar: OK

两行 OK 即完整性通过。

5.3 javac/java -cp 直接编译运行

mkdir -p /opt/bval-manual/src/demo /opt/bval-manual/classes && cp /opt/bval-demo/src/main/java/demo/BvalDemo.java /opt/bval-manual/src/demo/BvalDemo.java && javac -encoding UTF-8 -cp /opt/bval-manual/lib/jakarta.validation-api-3.0.2.jar -d /opt/bval-manual/classes /opt/bval-manual/src/demo/BvalDemo.java && LANG=C.UTF-8 java -Dfile.encoding=UTF-8 -cp "/opt/bval-manual/classes:/opt/bval-manual/lib/bval-jsr-3.0.2.jar:/opt/bval-manual/lib/jakarta.validation-api-3.0.2.jar" demo.BvalDemo | head -3

回显(实测):

ValidatorFactory 实现类: org.apache.bval.jsr.ApacheValidatorFactory
非法对象约束违反数: 4
  [email] 邮箱格式不合法 | 无效值 = not-an-email

javac 只需验证 API jar(注解与接口在规范包),运行时才需 bval-jsr 实现 jar,与方案 A 的最小 classpath 一致,方案 B 验证通过。

5.4 核对 jar 版本清单

java -jar /opt/bval-manual/lib/bval-jsr-3.0.2.jar

回显(实测):

Project: Apache BVal
Version: 3.0.2
Revision: unknown

os.name: Linux
os.version: 6.8.0-138-generic
cd /tmp && jar xf /opt/bval-manual/lib/bval-jsr-3.0.2.jar META-INF/MANIFEST.MF && grep -E "Specification-|Implementation-" META-INF/MANIFEST.MF

回显(实测):

Specification-Title: Jakarta Bean Validation
Specification-Version: 3.0
Implementation-Title: Apache BVal :: Implementation
Implementation-Version: 3.0.2
Build-Jdk-Spec: 11

MANIFEST 确认 3.0.2 实现 Jakarta Bean Validation 3.0 规范、运行底线 Java 11。

六、方案对比与选择建议

维度方案 A:Maven 依赖方案 B:Central 手动双 jar
依赖来源Maven 中央仓库(自动)repo1.maven.org(手动 wget)
所需 jarbval-jsr + bval-extras + jakarta.validation-apibval-jsr + jakarta.validation-api(最小)
是否需联网需(首次拉取依赖)需下载一次,之后可离线分发
版本管理改 pom.xml 版本号即可手动下载、自行管理目录
完整性校验Maven 仓库校验机制.sha1 拼行校验(无 .sha512,实测)
适用场景常规 Maven/Gradle 工程无构建工具的服务器、离线内网

关键差异与选型建议:工程内使用一律选方案 A;临时验证、离线机器用方案 B。需要 bval-extras 扩展约束时方案 A 加一个依赖即可(方案 B 需额外下载 bval-extras-3.0.2.jar,42057 字节,实测)。

七、多版本管理与升级、降级

7.1 Maven 方式的多版本共存

cd /opt/bval-demo && mvn -q dependency:get -Dartifact=org.apache.bval:bval-jsr:2.0.6 && ls /root/.m2/repository/org/apache/bval/bval-jsr/

回显(实测):

2.0.6
3.0.2

降级到 2.0.6 时必须同步:pom 中 jakarta.validation-api 改为 javax.validation:validation-api:2.0.1.Final,代码 import 从 jakarta.validation.* 改回 javax.validation.*(2.0.6 的 SPI 文件名为 META-INF/services/javax.validation.spi.ValidationProvider,实测 jar tf 确认)。

7.2 手动方式的多版本共存

历史版本 jar 按 Central 路径下载(.../org/apache/bval/bval-jsr/<版本>/bval-jsr-<版本>.jar);不同版本放不同目录,运行时 -cp 指定其一。类路径上只保留一个 BVal 版本,避免 Provider 冲突。

7.3 多 JDK 共存与切换

Ubuntu 侧 JDK 均来自 apt,update-alternatives 管理:

update-alternatives --list java 2>/dev/null | head -2

回显(实测,本机仅装 17 时):

若另装 openjdk-11,此处会列出两条路径;切换用 update-alternatives --set java <路径>。BVal 3.0.2 在 Java 11+ 均可运行,切换后重跑 4.5 节 BvalDemo 回归验证。

八、常见问题(FAQ)

Q1:报 NoClassDefFoundError: jakarta/validation/Validation? 运行 classpath 缺 jakarta.validation-api-3.0.2.jar。该 jar 在 bval-jsr 的 POM 中是 provided,Maven 环境必须显式声明依赖(见 4.2 节 pom),手动方案 -cp 必须带上双 jar(见 5.3 节)。

Q2:程序里的中文输出变成 ?(问号)怎么办? mvn -version 显示 platform encoding: ANSI_X3.4-1968 即为 locale 未配置 UTF-8。解决:运行前 export LANG=C.UTF-8,java 加 -Dfile.encoding=UTF-8(本文回显均在此设置下采集);编译侧由 pom 的 project.build.sourceEncoding=UTF-8 保证。mvn exec:java 可用 JAVA_TOOL_OPTIONS=-Dfile.encoding=UTF-8 一次性传给 JVM。

Q3:报 NoClassDefFoundError: javax/validation/Validation(或混用报找不到 Provider)? 命名空间混用:BVal 3.0.x 只认 jakarta.validation.*,2.0.x 只认 javax.validation.*,SPI 注册文件名也不同(jakarta.validation.spi.ValidationProvider vs javax.validation.spi.ValidationProvider)。排查:mvn dependency:tree | grep validation 确认 bval-jsr 版本与验证 API 版本、代码 import 三者匹配。

Q4:Maven 拉取依赖很慢或超时怎么办? 确认链路(curl -sI https://repo1.maven.org/... | head -1 应返回 HTTP/2 200,实测见 2.1 节),慢多为带宽问题;可改阿里云镜像(~/.m2/settings.xml <mirrors> 添加 https://maven.aliyun.com/repository/public,<mirrorOf>central</mirrorOf>)。离线机器直接走方案 B。

Q5:ValidationException: No validator provider found? classpath 上没有 BVal 实现 jar(只有验证 API 时 SPI 文件不存在)。确认 -cp 或依赖中包含 bval-jsr-3.0.2.jar。也可显式指定 Provider:Validation.byProvider(org.apache.bval.jsr.ApacheValidationProvider.class).configure().buildValidatorFactory()(实测可用,见《Apache BVal 快速入门与集成示例》)。

Q6:sha1 校验失败怎么处理? 删除坏文件重新 wget;若反复失败,检查代理是否改写二进制内容。校验通过(输出 OK)前不要使用该 jar。

九、卸载与清理

按「工程 → 本地仓库 → 系统包」顺序清理。

删除实验工程与手动安装目录:

rm -rf /opt/bval-demo /opt/bval-manual /tmp/bm

回显(实测,无输出即成功):

清理 Maven 本地仓库中的 BVal 与验证 API 缓存:

rm -rf /root/.m2/repository/org/apache/bval /root/.m2/repository/jakarta/validation && ls /root/.m2/repository/org/apache/bval

回显(实测):

ls: cannot access '/root/.m2/repository/org/apache/bval': No such file or directory

卸载系统级 Maven 与 JDK:

DEBIAN_FRONTEND=noninteractive apt-get purge -y maven openjdk-17-jdk-headless openjdk-17-jre-headless && apt-get autoremove -y

输出节选(实测首尾):

Removing maven (3.6.3-5) ...
Removing openjdk-17-jdk-headless:amd64 (17.0.20.1+1-1~22.04) ...
Processing triggers for libc-bin (2.35-0ubuntu3.15) ...

验证卸载结果:

java -version 2>&1; mvn -version 2>&1

回显(实测):

bash: java: command not found
bash: mvn: command not found

两条命令均报 command not found,卸载完成。

十、参考链接

  1. Apache BVal 项目主页:https://bval.apache.org/
  2. Maven 中央仓库 bval-jsr:https://repo1.maven.org/maven2/org/apache/bval/bval-jsr/
  3. Maven 中央仓库 jakarta.validation-api:https://repo1.maven.org/maven2/jakarta/validation/jakarta.validation-api/
  4. Apache BVal 官方下载(仅源码发行包):https://downloads.apache.org/bval/
  5. Jakarta Bean Validation 规范:https://jakarta.ee/specifications/bean-validation/3.0/