惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

The GitHub Blog
The GitHub Blog
云风的 BLOG
云风的 BLOG
T
Threatpost
WordPress大学
WordPress大学
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
PCI Perspectives
PCI Perspectives
T
The Exploit Database - CXSecurity.com
Y
Y Combinator Blog
雷峰网
雷峰网
爱范儿
爱范儿
The Hacker News
The Hacker News
Last Week in AI
Last Week in AI
Simon Willison's Weblog
Simon Willison's Weblog
T
Tor Project blog
S
Securelist
宝玉的分享
宝玉的分享
L
LangChain Blog
O
OpenAI News
AI
AI
P
Privacy International News Feed
L
LINUX DO - 最新话题
D
DataBreaches.Net
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
Attack and Defense Labs
Attack and Defense Labs
罗磊的独立博客
M
MIT News - Artificial intelligence
Security Archives - TechRepublic
Security Archives - TechRepublic
月光博客
月光博客
博客园 - 【当耐特】
T
Tailwind CSS Blog
C
Cybersecurity and Infrastructure Security Agency CISA
H
Help Net Security
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
博客园_首页
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
Hacker News - Newest:
Hacker News - Newest: "LLM"
腾讯CDC
Jina AI
Jina AI
The Last Watchdog
The Last Watchdog
K
Kaspersky official blog
Webroot Blog
Webroot Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Blog — PlanetScale
Blog — PlanetScale
MyScale Blog
MyScale Blog
MongoDB | Blog
MongoDB | Blog
P
Proofpoint News Feed
Recorded Future
Recorded Future
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
博客园 - 三生石上(FineUI控件)
The Cloudflare Blog

博客园_首页

Linux实操--组管理、权限管理和定时任务 Java + EasyExcel 实现单个接口导出多个Excel Mem0 源码解析系列(二):提示词工程的深度剖析 Openclaw TaskFlow究竟是什么?和普通Skill技能有什么区别 博文阅读密码验证 - 博客园 嘉立创开源:应该是全网MicroPython教程最多的开发板 Hermes Agent 集成实践:从协议到生产 2026年AI编程工具横评:Cursor、Codex、Claude Code、Zed、Windsurf Java程序员必看的RAG入门教程 2026 AI效率神器:Superpowers + Claude Code 保姆级教程 本地大模型部署全攻略:从 0 到 1 玩转 Ollama 【从0到1构建一个ClaudeAgent】内存管理-上下文压缩 .NET 高级开发 | 设计、实现一个事件总线框架 电子小白入门之NE555 3. WorkBuddy:隐藏玩法,一键召唤专家,让 AI 以"专家身份"给你干活 和AI一起搞事情#3:Claude Teammate 游戏开发翻车实录 【OpenClaw】通过 Nanobot 源码学习架构---(7)Memory C# .NET 周刊|2026年3月3期 我在 Debian 11 上把 K8s 单机搭起来了,过程没你想的那么顺(/opt 目录版) 深度学习进阶(七)Data-efficient Image Transformer CLI+Skill搭建浏览器AI自动化框架,告别一切重复枯燥任务 告别Token账单无底洞:OpenClaw本地部署,重塑企业数据主权的唯一解 FastAPI+Vue:文件分片上传+秒传+断点续传,这坑我帮你踩平了! SBTI 爆火后,我做了个程序员版的 CBTI。。已开源 + 附开发过程 多模态检索开始进入工程期:用 Sentence Transformers 搭建可落地的 Multimodal RAG 100多行代码实现一个最简单的Agent(用ReAct) Claude Code 通关手册(八):推荐 5 个 Hooks,代码质量提升 3 倍 老板:“有人截图了!”。安全部门:“收到,马上查暗水印!” - why技术 技术之外,皆是人间 C#/.NET/.NET Core技术前沿周刊 | 第 69 期(2026年4.01-4.12) Snack JSONPath 项目架构分析 Claude Code Buddy 小析:一个非核心功能,如何体现产品的细节完成度 AI新时代下的图床管理方案-Cloudflare图床+MCP+Skills方案指南 化繁为简:顺丰速运App如何通过 HarmonyOS SDK实现专业级空间测量 从零实现富文本编辑器#13-React非编辑节点的内容渲染 AI开发-python-langchain框架(3-23-OpenAI Functions风格Tool Calling智能助手) .NET + AI 进阶实战:基于类的技能开发 - 打造可治理的 Agent 能力模块 【从0到1构建一个ClaudeAgent】规划与协调-技能 上周热点回顾(4.6-4.12) 电子小白的工具三件套:面包板、杜邦线、万能板 单表五亿数据的查询优化 | Mysql、StarRocks 2. WorkBuddy:从“我是谁”到“帮我干活” C# 如何减少代码运行时间:7 个实战技巧 基于HelixToolkit.SharpDX 渲染3D模型 - 笺上知微 从零开始的双臂具身VLA起源及现阶段发展综述 - SkyXZ 记对 xonsh shell 的使用, 脚本编写, 迁移及调优 - pluvium27 受够了Vibe Coding的失控?换个起点,让AI事半功倍 从开始配置漏洞环境到漏洞复现流程 - 難しい 关于10年工作经验的程序员对OpenClaw的实战经验分享以及看法 - 虚无境 Any metadata 的内存布局 C# .NET 周刊|2026年3月2期 - InCerry 我帮你测过了,测试圈排名第二的 Skill 依然很牛逼 Skill Discovery | 无监督技能发现的经典工作总结 - MoonOut PbootCMS 网站内容数量多导致访问慢?这些实用优化方案帮你提速! - 家兴网络技术工作室 上下文工程是什么?过时了么?一文讲明白! - 一枫说码 网站漏洞怎么发现并修复?一篇实用指南(附完整流程) - 家兴网络技术工作室 开了 TUN 模式还是直连?90% 的人都踩过这个坑 Github日报|2026年04月12日 - AI一族 AScript扩展多种脚本语言 - rockey627 AI 学习笔记:Agent 的记忆机制 你能被装进一个文件里吗?——7 万人把同事"蒸馏"成了 AI - 我没有三颗心脏 Claude Code 通关手册(七):给 AI 装上技能包——Skills 完全指南 - 暮色之狐 在浏览器中快速编辑代码:VSCode Web 集成实践 - Newbe36524 蒸馏自己 skill?基于 Deepseek 的蒸馏器,丐版蒸馏方式,简单便捷 - To_Carpe_Diem Spring AI Aliababa和AgentScope,哪个更好? - 苏三说技术 Etsy 把 1000 个 MySQL 分片迁进 Vitess:425TB 数据背后的真正问题不是性能,而是运维规模 MicroPython LVGL基础知识和概念:底层渲染与性能优化 - FreakStudio 数据库草图算法 Python 潮流周刊#146:CPython 引入 Rust 的进展 - 豌豆花下猫 最小生成树 - mofei1116 红日靶场七:从外网入口、容器逃逸到 AD 接管的完整利用链复盘 - YouDiscovered1t 分享四款开源且实用的 Kafka 管理工具 - 追逐时光者 vLLM 权重加载机制全解析:从挑战到理想架构 LCT 学习笔记 - ACehomoxue Avalonia UI 12.0.0 正式发布:架构演进和性能飞跃 - 张善友 当 AI Agent 把调用链拉长,延迟开始成为一门生意 conhost.exe 无法显示 U+2717 - 145a 太秀了,我把自己蒸馏成了 Skill!已开源 - 程序员鱼皮 ASP.NET Core 内存缓存实战:一篇搞懂该怎么配、怎么避坑 基于 Ghostty 带有分割标签页和为 Claude 编程设计的通知终端 - BugShare AI 焊死入口:教育的“操作系统级”重塑 - 郝hai 初级Java开发工程师使用sql脚本编写代码的过程是简单而且不糊涂 - CoderOilStation Claude Code通关手册(六):MCP协议完全指南 - 暮色之狐 边框灯光环绕动画特效实现指南 - Newbe36524 开源:子木蒸馏版的 SEO 审计工具 seo-audit-skill v1.0 我所理解的Python元模型 【从0到1构建一个ClaudeAgent】规划与协调-TodoWrite - 程序员Seven Claude 和 Codex 在审计 Skill 上性能差异探究 - ACai_sec AScript如何实现中文脚本引擎 - rockey627 【渗透测试】HTB Season10 Garfield 全过程wp - dynasty_chenzi Android 开发者为什么必须掌握 AI 能力?端侧视角下的技术变革 树状数组正确性证明 - AC-wyr 你的 AI 焦虑,可能比 AI 本身更危险——ATM 机没有消灭银行柜员,但恐慌消灭了你的判断力 - 我没有三颗心脏 一个拉胯的分库分表方案有多绝望?整个部门都在救火! - 冰河团队 动态规划入门必学之走方格问题 - Ofnoname PostgREST 与 PostgreSQL 角色权限配置全解析(生产级实践) - SheepDog1998 使用 UEFI 图形输出协议 GOP 在屏幕上显示图像的方法 - 阿源- Claude Code通关手册(五):组建你的AI专家团队,子代理系统 - 暮色之狐 一个程序员到架构师的催婚路之感悟(整整10年后的催婚相亲感悟) - MisterLip 用 Agent Skill 自动生成工作周报 - 赵康
Windows x64 构建 liboqs-java教程
云烟飘渺PM · 2026-06-19 · via 博客园_首页

Windows 下构建 liboqs-java,实现 PQC 算法的调用

liboqs-java 本身不是一个纯 Java 库,它底层依赖 liboqs 这个 C 语言实现的后量子密码学库。也就是说,我们最终虽然是在 Java / Spring Boot 项目里调用 PQC 算法,但真正执行算法逻辑的是 native 层。

本教程的目标如下:

  1. 在 Windows 上编译 liboqs
  2. 构建出可用的 liboqs-java.jar
  3. 运行官方示例验证构建是否成功
  4. 在 Spring Boot 项目中引入该 JAR
  5. 通过 Java 代码调用 ML-KEM 等后量子密码算法

环境与工具

Windows 10 / Windows 11
+ MinGW-w64
+ CMake
+ JDK
+ Maven

1. 先理解 liboqs 和 liboqs-java 的关系

在开始构建之前,先简单理一下几个组件之间的关系。

Spring Boot / Java 业务代码
        |
        | 调用 Java API
        v
liboqs-java.jar
        |
        | JNI 调用
        v
oqs-jni.dll
        |
        | 链接
        v
liboqs.a / liboqs
        |
        | 实际执行算法
        v
ML-KEM、ML-DSA 等 PQC 算法

可以这样理解:

组件 作用
liboqs C 语言实现的后量子密码学算法库
liboqs-java liboqs 的 Java 封装
oqs-jni.dll Java 和 native 层之间的 JNI 桥接库
liboqs-java.jar Java 项目最终要引入的 JAR 包

所以构建顺序一定是:

  1. 先构建 liboqs
  2. 再构建 liboqs-java
  3. 最后在 Java / Spring Boot 项目中引用生成的 JAR

如果跳过第一步,直接构建 liboqs-java,通常会遇到找不到 oqs.h、找不到 liboqs.a 之类的问题。


2. 构建时候的项目目录结构

因为需要在github上获取liboqs与libqos-java两个项目源码,构建时候建议最终的目录结构如下:

D:\workspace\liboqs-java-main
├── pom.xml
├── README.md
├── examples
│   ├── KEMExample.java
│   ├── SigExample.java
│   └── RandExample.java
├── src
├── liboqs
│   ├── CMakeLists.txt
│   ├── src
│   └── build
│       ├── include
│       │   └── oqs
│       │       └── oqs.h
│       └── lib
│           └── liboqs.a
└── target
    └── liboqs-java.jar

其中比较关键的是这几个文件:

liboqs\build\include\oqs\oqs.h
liboqs\build\lib\liboqs.a
target\liboqs-java.jar

只要这几个文件都生成了,说明主流程基本走通了。


3. 准备构建工具

需要提前安装下面几个工具。

工具 用途
MinGW-w64 提供 gccg++,用于编译 C 代码和 JNI 代码
CMake 生成并驱动 liboqs 的构建
JDK 编译 Java 代码,同时提供 JNI 头文件
Maven 构建 liboqs-java 并打包 JAR
Git 拉取源码,非必需,也可以手动下载 ZIP

建议所有工具都安装在英文路径下,不要放在带中文或空格的目录里。例如:

D:\c_tools\mingw64
D:\java\jdk-21
D:\javaTools\apache-maven-3.9.x
D:\workspace

这是因为 native 构建工具对路径比较敏感,中文路径或空格路径有时会带来一些很难排查的问题。


4. 安装 MinGW-w64

可以使用 WinLibs 提供的 MinGW-w64 发行版。

下载地址:

https://winlibs.com/

选择 Windows x86_64 版本即可。下载后解压到类似下面的目录:

D:\c_tools\mingw64

确认下面几个文件存在:

D:\c_tools\mingw64\bin\gcc.exe
D:\c_tools\mingw64\bin\g++.exe
D:\c_tools\mingw64\bin\mingw32-make.exe

后面 CMake 会通过这些工具来编译 liboqs 和 JNI 代码。


5. 安装 CMake

可以使用 winget 安装:

winget install Kitware.CMake

也可以从官网下载 Windows x64 Installer:

https://cmake.org/download/

安装时建议勾选:

Add CMake to the system PATH

安装完成后,重新打开一个 PowerShell,执行:

cmake --version

能看到版本号就说明 CMake 已经可以正常使用。


6. 安装 JDK

JDK 可以使用 Eclipse Temurin 或 Oracle JDK。

下载地址:

https://adoptium.net/
https://www.oracle.com/java/technologies/downloads/

本文示例使用 JDK 21,安装路径假设为:

D:\java\jdk-21

需要确认以下文件存在:

D:\java\jdk-21\bin\java.exe
D:\java\jdk-21\bin\javac.exe
D:\java\jdk-21\include\jni.h

其中 jni.h 很重要。构建 liboqs-java 时会编译 JNI 代码,如果安装的是 JRE 而不是 JDK,就会缺少这个头文件。


7. 安装 Maven

从 Maven 官网下载 binary zip 包:

https://maven.apache.org/download.cgi

解压到:

D:\javaTools\apache-maven-3.9.x

确认下面文件存在:

D:\javaTools\apache-maven-3.9.x\bin\mvn.cmd

8. 配置环境变量

这是 Windows 下最容易出问题的一步。

建议配置以下用户变量:

变量名 示例值
JAVA_HOME D:\java\jdk-21
MAVEN_HOME D:\javaTools\apache-maven-3.9.x
MinGW_HOME D:\c_tools\mingw64

然后把下面几个目录加入 Path

D:\c_tools\mingw64\bin
D:\java\jdk-21\bin
D:\javaTools\apache-maven-3.9.x\bin

配置完成后,一定要关闭当前已经打开的 PowerShell、cmd 或 IDE 终端,然后重新打开一个新的终端。

环境变量不会自动刷新到已经打开的终端窗口里。


9. 检查构建环境

重新打开 PowerShell,依次执行下面几条命令:

gcc --version
g++ --version
cmake --version
java -version
javac -version
mvn -version

每一条都应该正常输出版本信息。

如果某一条提示“不是内部或外部命令”,先不要继续构建,回去检查 Path 是否配置正确。


10. 获取源码

进入自己的工作目录:

cd D:\workspace

克隆 liboqs-java

git clone https://github.com/open-quantum-safe/liboqs-java.git liboqs-java-main

进入项目目录:

cd liboqs-java-main

再把 liboqs 克隆到当前项目内部,目录名必须叫 liboqs

git clone https://github.com/open-quantum-safe/liboqs.git liboqs

完成后检查目录:

Test-Path .\pom.xml
Test-Path .\liboqs\CMakeLists.txt

两条命令都返回 True,说明源码位置没有放错。

如果不想使用 Git,也可以直接从 GitHub 下载 ZIP。需要注意的是,需要将解压出来的目录名称进行更换。'liboqs-java'对应的项目目录命名liboqs-java-main ;liboqs对应的目录 liboqs-main目录重命名为 liboqs,并放到 liboqs-java-main 目录下。


11. 构建 liboqs

先进入 liboqs 目录:

cd D:\workspace\liboqs-java-main\liboqs

如果之前构建失败过,建议先删除旧的 build 目录:

Remove-Item -Recurse -Force build -ErrorAction SilentlyContinue

然后执行 CMake 配置:

cmake -G "MinGW Makefiles" `
  -DCMAKE_C_COMPILER=gcc `
  -DCMAKE_ASM_COMPILER=gcc `
  -DBUILD_SHARED_LIBS=OFF `
  -S . `
  -B build

这里几个参数比较关键:

参数 说明
-G "MinGW Makefiles" 使用 MinGW 的构建方式
-DCMAKE_C_COMPILER=gcc 指定 C 编译器
-DCMAKE_ASM_COMPILER=gcc 指定汇编编译器,避免 ASM 编译器找不到
-DBUILD_SHARED_LIBS=OFF 构建静态库 liboqs.a
-S . 源码目录为当前目录
-B build 构建目录为 build

如果配置成功,最后会看到类似输出:

-- Configuring done
-- Generating done
-- Build files have been written to: .../liboqs/build

接着开始编译:

cmake --build build -j4

-j4 表示使用 4 个线程并行构建。如果机器配置较好,可以改成 -j8;如果内存比较紧张,可以改成 -j2

构建完成后检查产物:

Test-Path .\build\lib\liboqs.a
Test-Path .\build\include\oqs\oqs.h

两条命令都返回 True,说明 liboqs 已经构建完成。


12. 构建 liboqs-java.jar

回到 liboqs-java 项目根目录:

cd D:\workspace\liboqs-java-main

执行 Maven 打包:

mvn package -Pwindows "-Dmaven.test.skip=true"

这里要注意 PowerShell 下的写法。

-Dmaven.test.skip=true 建议加上双引号,否则 PowerShell 有时会把它解析错,导致 Maven 报类似下面的错误:

Unknown lifecycle phase ".test.skip=true"

如果一切正常,最后会看到:

[INFO] BUILD SUCCESS

检查 JAR 是否生成:

dir .\target\liboqs-java.jar

也可以确认 JAR 中是否包含 JNI 动态库:

jar tf .\target\liboqs-java.jar | findstr oqs-jni

正常情况下会看到:

oqs-jni.dll

这一步成功后,target\liboqs-java.jar 就是后面 Spring Boot 项目需要引入的包。


13. 运行官方 KEM 示例

先编译示例代码:

javac -cp target\liboqs-java.jar examples\KEMExample.java

如果没有输出错误,说明编译成功。

然后运行:

java -cp "target\liboqs-java.jar;examples\" KEMExample

Windows 下 classpath 的分隔符是分号 ;,这一点和 Linux / macOS 不一样。

如果运行成功,输出中会看到类似内容:

Supported KEMs:
...

Enabled KEMs:
...

KEM Details:
  Name: ML-KEM-512
  ...

Shared secrets coincide? true

重点看最后这一行:

Shared secrets coincide? true

这说明双方通过 KEM 算法协商出来的共享密钥一致,liboqs-java 已经可以正常调用 native 层算法。

还可以继续测试签名示例:

javac -cp target\liboqs-java.jar examples\SigExample.java
java -cp "target\liboqs-java.jar;examples\" SigExample

14. 在 Spring Boot 项目中引入 liboqs-java.jar

构建完成后,就可以把 liboqs-java.jar 放到自己的 Spring Boot 项目里使用。

假设 Spring Boot 项目结构如下:

pqc-demo
├── lib
│   └── liboqs-java.jar
├── pom.xml
└── src
    └── main
        └── java

把刚才生成的文件复制过去:

D:\workspace\liboqs-java-main\target\liboqs-java.jar

放到:

pqc-demo\lib\liboqs-java.jar

14.1 方式一:直接使用 system 依赖

pom.xml 中加入:

<dependency>
    <groupId>org.openquantumsafe</groupId>
    <artifactId>liboqs-java</artifactId>
    <version>3.0</version>
    <scope>system</scope>
    <systemPath>${project.basedir}/lib/liboqs-java.jar</systemPath>
</dependency>

这里的 version 可以根据你实际构建的 liboqs-java 版本调整。最稳妥的方式是看一下 liboqs-java-main/pom.xml 中的版本号。

这种方式适合本地测试,简单直接。

不过 system 依赖不是 Maven 推荐的长期方案。如果项目需要给团队其他人使用,或者要放到 CI/CD 里构建,更建议使用下面这种方式。


14.2 方式二:安装到本地 Maven 仓库

liboqs-java.jar 所在目录执行:

mvn install:install-file `
  "-Dfile=liboqs-java.jar" `
  "-DgroupId=org.openquantumsafe" `
  "-DartifactId=liboqs-java" `
  "-Dversion=3.0" `
  "-Dpackaging=jar"

安装完成后,Spring Boot 项目里就可以正常写 Maven 依赖:

<dependency>
    <groupId>org.openquantumsafe</groupId>
    <artifactId>liboqs-java</artifactId>
    <version>3.0</version>
</dependency>

如果是团队项目,也可以把这个 JAR 发布到 Nexus、Artifactory 或公司内部 Maven 仓库中。


15. Spring Boot 中调用 ML-KEM

下面写一个简单的 Service,用来演示如何在 Spring Boot 中调用 KEM 算法。

示例使用 ML-KEM-512

package com.example.pqcdemo.service;

import org.openquantumsafe.KeyEncapsulation;
import org.springframework.stereotype.Service;

import java.util.Arrays;

@Service
public class PqcKemService {

    public boolean testMlKem512() throws Exception {
        KeyEncapsulation client = null;
        KeyEncapsulation server = null;

        try {
            client = new KeyEncapsulation("ML-KEM-512");
            server = new KeyEncapsulation("ML-KEM-512");

            // 客户端生成公钥
            byte[] publicKey = client.generate_keypair();

            // 服务端使用客户端公钥封装共享密钥
            byte[] ciphertext = server.encap_secret(publicKey);
            byte[] serverSharedSecret = server.get_shared_secret();

            // 客户端使用密文解封装共享密钥
            byte[] clientSharedSecret = client.decap_secret(ciphertext);

            // 判断两端共享密钥是否一致
            return Arrays.equals(clientSharedSecret, serverSharedSecret);
        } finally {
            if (client != null) {
                client.dispose_KEM();
            }
            if (server != null) {
                server.dispose_KEM();
            }
        }
    }
}

再写一个 Controller 方便测试:

package com.example.pqcdemo.controller;

import com.example.pqcdemo.service.PqcKemService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class PqcController {

    private final PqcKemService pqcKemService;

    public PqcController(PqcKemService pqcKemService) {
        this.pqcKemService = pqcKemService;
    }

    @GetMapping("/pqc/ml-kem-512/test")
    public String testMlKem512() throws Exception {
        boolean result = pqcKemService.testMlKem512();
        return "ML-KEM-512 shared secret match: " + result;
    }
}

启动 Spring Boot 后访问:

http://localhost:8080/pqc/ml-kem-512/test

如果返回:

ML-KEM-512 shared secret match: true

说明 Spring Boot 已经成功调用 liboqs-java 中的 PQC 算法。


16. 查看当前可用的 KEM 算法

如果不确定当前构建出来的库启用了哪些 KEM 算法,可以写一个接口打印出来:

package com.example.pqcdemo.controller;

import org.openquantumsafe.KEMs;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
public class PqcAlgorithmController {

    @GetMapping("/pqc/kems")
    public List<String> listEnabledKems() {
        return KEMs.get_enabled_KEMs();
    }
}

访问:

http://localhost:8080/pqc/kems

可以看到当前 native 库中实际启用的 KEM 列表。

需要注意:

  • Supported KEMs 表示库认识哪些算法名称
  • Enabled KEMs 表示当前构建产物里真正启用了哪些算法

实际项目中应该以 Enabled KEMs 为准。


17. Spring Boot 打包时需要注意的问题

如果你只是本地运行,一般直接引入 liboqs-java.jar 就可以。

但如果要打成 Spring Boot 可执行 JAR,需要注意依赖是否真的被打进最终包里。

如果使用 system 依赖,可以在 spring-boot-maven-plugin 中增加配置:

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <configuration>
                <includeSystemScope>true</includeSystemScope>
            </configuration>
        </plugin>
    </plugins>
</build>

不过更推荐的方式还是把 liboqs-java.jar 安装到本地 Maven 仓库,或者发布到私有 Maven 仓库,然后按普通依赖方式引入。

这样 Maven、IDE、CI/CD 都更容易处理。


18. 常见问题记录

18.1 gcc 找不到

报错示例:

gcc is not recognized
The C compiler identification is unknown

一般是 MinGW 的 bin 目录没有加入 Path

检查:

gcc --version

如果不正常,确认下面路径是否已经加入环境变量:

D:\c_tools\mingw64\bin

修改后需要重新打开终端。


18.2 CMake 找不到 ASM 编译器

报错示例:

No CMAKE_ASM_COMPILER could be found

配置 liboqs 时加上:

-DCMAKE_ASM_COMPILER=gcc

也就是完整命令使用:

cmake -G "MinGW Makefiles" `
  -DCMAKE_C_COMPILER=gcc `
  -DCMAKE_ASM_COMPILER=gcc `
  -DBUILD_SHARED_LIBS=OFF `
  -S . `
  -B build

18.3 找不到 oqs/oqs.h

报错示例:

fatal error: oqs/oqs.h: No such file or directory

说明 liboqs 没有构建好,或者 liboqs-java 没有找到正确的 include 目录。

先检查:

Test-Path .\liboqs\build\include\oqs\oqs.h

如果返回 False,先回到 liboqs 目录重新构建。


18.4 找不到 liboqs.a

检查文件是否存在:

Test-Path .\liboqs\build\lib\liboqs.a

如果不存在,说明 liboqs 构建没有完成,重新执行:

cd D:\workspace\liboqs-java-main\liboqs
cmake --build build -j4

18.5 找不到 jni.h

报错示例:

fatal error: jni.h: No such file or directory

通常是 JAVA_HOME 指向了 JRE,或者没有正确配置 JDK。

检查:

Test-Path "$env:JAVA_HOME\include\jni.h"

应该返回:

True

如果不是,重新设置 JAVA_HOME 到 JDK 根目录。


18.6 PowerShell 中 Maven 参数解析错误

报错示例:

Unknown lifecycle phase ".test.skip=true"

把 Maven 参数用双引号包起来:

mvn package -Pwindows "-Dmaven.test.skip=true"

18.7 Spring Boot 运行时报 native 库相关错误

如果出现类似 native library 加载失败的问题,先确认:

jar tf liboqs-java.jar | findstr oqs-jni

能看到:

oqs-jni.dll

如果 JAR 中没有这个文件,说明 liboqs-java 构建过程不完整,需要重新构建。

如果 JAR 中有 oqs-jni.dll,但 Spring Boot 运行仍然失败,可以先在普通 Java main 方法中运行官方 KEMExample,确认是不是 Spring Boot 打包方式导致的问题。


19. 一组完整构建命令

如果工具和环境变量都已经配置好,可以直接按下面流程执行。

把路径换成自己的实际路径:

$PROJECT = "D:\workspace\liboqs-java-main"

cd "$PROJECT\liboqs"

Remove-Item -Recurse -Force build -ErrorAction SilentlyContinue

cmake -G "MinGW Makefiles" `
  -DCMAKE_C_COMPILER=gcc `
  -DCMAKE_ASM_COMPILER=gcc `
  -DBUILD_SHARED_LIBS=OFF `
  -S . `
  -B build

cmake --build build -j4

cd $PROJECT

mvn package -Pwindows "-Dmaven.test.skip=true"

javac -cp target\liboqs-java.jar examples\KEMExample.java

java -cp "target\liboqs-java.jar;examples\" KEMExample

看到:

Shared secrets coincide? true

就说明构建成功。


21. 小结

整个流程看起来步骤不少,但真正关键的地方其实只有几个:

  1. MinGW、CMake、JDK、Maven 必须都能在命令行正常使用
  2. liboqs 要先构建成功
  3. liboqs-java 构建时要能找到 oqs.hliboqs.a
  4. 最终生成的 liboqs-java.jar 中要包含 oqs-jni.dll
  5. Spring Boot 引入时要确保 JAR 被正确加入运行时 classpath

如果官方示例 KEMExample 能跑通,并且输出:

Shared secrets coincide? true

那么后续在 Spring Boot 中调用 ML-KEM、ML-DSA 等 PQC 算法,基本就是普通 Java API 调用的问题了。