Java 跨平台硬件采集终极方案:Oshi 全解析
GitHub 星标超 6k+的开源项目(纯 Java 实现(少量 JNA 调用,无需编译 native 代码)支持 Windows / Linux / macOS / FreeBSD / Solaris / AIXMIT 许可证,商业友好活跃维护(截至 2025 年仍在持续更新)Oshi = Java 跨平台硬件信息采集的“瑞士军刀”它不是魔法,却用优雅的工程设计,在 Java 的沙箱中凿出一扇通
·
打破 OS 壁垒:Java 跨平台硬件信息采集的“终极方案”
Java 以“一次编写,到处运行”著称,但在硬件信息采集(如 CPU 型号、内存大小、磁盘序列号、网卡 MAC、温度传感器等)这类底层操作上,长期受限于 JVM 的沙箱机制和跨平台抽象——标准 Java API 并不提供直接访问硬件的能力。
然而,随着现代应用对系统监控、设备指纹、授权绑定等需求的增长,开发者迫切需要一种真正跨平台、安全可靠、维护成本低的硬件信息采集方案。本文将揭示目前最接近“终极”的解决方案。
一、为什么 Java 原生做不到?
- JVM 抽象层屏蔽了底层细节:
Runtime.getRuntime().availableProcessors()只能获取逻辑核数,无法得知 CPU 型号。 - 无统一硬件接口:Windows 用 WMI,Linux 读
/proc或dmidecode,macOS 依赖system_profiler或 IOKit。 - 权限与安全限制:部分信息(如 BIOS 序列号)需 root/Admin 权限,Java 默认无法提权。
❌ 单纯依赖
System.getProperty()或 JMX(如OperatingSystemMXBean)只能获取有限信息。
二、“伪跨平台”方案的缺陷
| 方案 | 问题 |
|---|---|
Runtime.exec() 调用 shell 命令 |
需为每个 OS 编写不同命令;易受环境变量、路径、权限影响;存在注入风险 |
| JNI 自研本地库 | 需编译 .dll/.so/.dylib;维护多平台 native 代码成本高;部署复杂 |
| 第三方 Java 库(如 Sigar、JNativeHook) | 多已停止维护;兼容性差(尤其 ARM/M1/M2);许可证风险 |
这些方案要么“跨平台但脆弱”,要么“强大但不跨平台”。
三、终极方案:Oshi(Operating System and Hardware Information)
✅ 什么是 Oshi?
- GitHub 星标超 6k+ 的开源项目(https://github.com/oshi/oshi)
- 纯 Java 实现(少量 JNA 调用,无需编译 native 代码)
- 支持 Windows / Linux / macOS / FreeBSD / Solaris / AIX
- MIT 许可证,商业友好
- 活跃维护(截至 2025 年仍在持续更新)
✅ 核心优势
| 特性 | 说明 |
|---|---|
| 统一 API | 一套代码获取所有平台硬件信息 |
| 深度信息覆盖 | CPU、内存、磁盘、网络、USB、传感器、固件等 |
| 自动适配 OS | 内部通过 JNA 调用系统 API(WMI、sysctl、/proc 等) |
| 无外部依赖 | 仅需 oshi-core + jna 两个 JAR |
| 安全可控 | 不执行 shell 命令,避免注入风险 |
四、实战示例
1. Maven 依赖
<dependency>
<groupId>com.github.oshi</groupId>
<artifactId>oshi-core</artifactId>
<version>6.6.3</version> <!-- 2025年最新稳定版 -->
</dependency>
2. 获取关键硬件信息
import oshi.SystemInfo;
import oshi.hardware.HardwareAbstractionLayer;
import oshi.software.os.OperatingSystem;
public class HardwareInfo {
public static void main(String[] args) {
SystemInfo si = new SystemInfo();
HardwareAbstractionLayer hal = si.getHardware();
OperatingSystem os = si.getOperatingSystem();
// CPU
System.out.println("CPU: " + hal.getProcessor().toString());
// 内存
System.out.println("Total Memory: " + hal.getMemory().getTotal() / (1024 * 1024 * 1024) + " GB");
// 磁盘
hal.getDiskStores().forEach(disk ->
System.out.println("Disk: " + disk.getModel() + ", Serial: " + disk.getSerial()));
// 网络 MAC
hal.getNetworkIFs().forEach(net ->
System.out.println("MAC: " + net.getMacaddr()));
// 主板/固件(部分平台支持)
System.out.println("Motherboard: " + hal.getComputerSystem().getBaseboard().getModel());
System.out.println("BIOS Serial: " + hal.getComputerSystem().getFirmware().getBiosVersion());
// OS 信息
System.out.println("OS: " + os.toString());
}
}
3. 输出示例(Windows)
CPU: Intel(R) Core(TM) i7-11800H @ 2.30GHz (8 cores, 16 threads)
Total Memory: 32 GB
Disk: Samsung SSD 980 PRO 1TB, Serial: S6Z4NS0R800323
MAC: 00:1A:2B:3C:4D:5E
Motherboard: ROG Zephyrus G15
BIOS Serial: GA503QM.314
OS: Windows 11 10.0 build 22631
五、高级能力(Oshi 独有)
- 传感器数据(温度、风扇转速):
hal.getSensors().getCpuTemperature(); // ℃ - 电池状态(笔记本/UPS):
hal.getPowerSources().get(0).getRemainingCapacityPercent(); - USB 设备枚举:
hal.getUsbDevices(true).forEach(usb -> System.out.println(usb.getName()));
⚠️ 注意:部分敏感信息(如 BIOS 序列号)在 macOS 上因安全策略可能返回空值,这是操作系统限制,非 Oshi 之过。
六、为什么它是“终极方案”?
| 维度 | Oshi 表现 |
|---|---|
| 跨平台性 | ✅ 支持所有主流桌面/服务器 OS |
| 维护成本 | ✅ 纯 Java + JNA,无 native 编译 |
| 信息深度 | ✅ 覆盖 90%+ 常用硬件指标 |
| 安全性 | ✅ 无 shell 执行,无 JNI 风险 |
| 社区活跃度 | ✅ 持续更新,Issue 响应及时 |
| 企业采用 | ✅ 被 Prometheus JMX Exporter、Elastic Agent 等项目集成 |
七、局限与应对
| 局限 | 应对建议 |
|---|---|
| ARM/Linux 嵌入式支持有限 | 结合 /proc/cpuinfo 等 fallback 机制 |
| macOS 安全限制严格 | 引导用户授予权限(如“完全磁盘访问”) |
| 实时性要求极高场景 | Oshi 非实时库,高频采样需缓存结果 |
结语
Oshi = Java 跨平台硬件信息采集的“瑞士军刀”
它不是魔法,却用优雅的工程设计,在 Java 的沙箱中凿出一扇通往硬件世界的窗。
对于绝大多数企业级、IoT、监控或授权场景,Oshi 已是事实上的“终极方案”。
更多推荐



所有评论(0)