Java
xyz.darra:darra-ai 是对 darra_ai.h 的 JNI 薄封装:只翻译类型和错误码,不另造语义,零密码学。权威契约 = Core/include/darra_ai.h;hint 文案与 错误码 逐字一致。
公开 runtime 包只含解密、验票、推理分发、诊断、运行时包管理。物理上没有 darra_encrypt_ / darra_issue_ / darra_fingerprint_ 符号。
主 jar 纯 Java,不内嵌 dll/so。native(DarraAI.Core + darraai_jni)按 classifier 另打。
本文档对应 Java SDK v1.0.0(AiRuntime.VERSION_MAJOR/MINOR/PATCH,与头文件 DARRA_VERSION_* 同一组数字)。加载后核 ABI:darra_version() 的 major 必须等于 NativeLoader.HEADER_MAJOR(1),不等拒绝继续。客户机 AiRuntime.versionString() 必须看到 1.0.0+runtime。
包名 xyz.darra.ai。方法 camelCase(openPlain / inferImage)。错误是 AiException 的嵌套子类:AiException.IoNotFoundException。会话实现 AutoCloseable,用 try-with-resources。
安装
- Maven
- Gradle
- 手动引用 JAR
<dependency>
<groupId>xyz.darra</groupId>
<artifactId>darra-ai</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>xyz.darra</groupId>
<artifactId>darra-ai</artifactId>
<version>1.0.0</version>
<classifier>natives-windows-x86_64</classifier>
</dependency>
Linux x64 把 classifier 换成 natives-linux-x86_64;Linux ARM64 / RK3588 用 natives-linux-aarch64。
implementation 'xyz.darra:darra-ai:1.0.0'
implementation 'xyz.darra:darra-ai:1.0.0:natives-windows-x86_64'
不走 Maven/Gradle 时:
- 从 下载页面 取主 jar 与对应平台 natives
- 主 jar 加入 classpath
- natives 用系统属性
xyz.darra.ai.natives.dir指向目录,或放进java.library.path
包坐标与仓内既有 Java SDK 一致:groupId=xyz.darra(EtherCAT darra-ethercat-master、OPC UA darra-opcua-sdk、PnS darra-pns-slave)。artifactId=darra-ai。JDK 17(maven.compiler.release 17)。
natives classifier
| classifier | 内容 | 使用场景 |
|---|---|---|
| natives-windows-x86_64 | DarraAI.Core.dll + darraai_jni.dll | Windows x64 runtime |
| natives-linux-x86_64 | libCore.so + libdarraai_jni.so | Linux x64 runtime |
| natives-linux-aarch64 | 同上 so | Linux ARM64 / RK3588 runtime |
classifier jar 内资源路径(NativeLoader 从 classpath 抽出):
natives/windows-x86_64/DarraAI.Core.dll
natives/windows-x86_64/darraai_jni.dll
natives/linux-x86_64/libCore.so
natives/linux-x86_64/libdarraai_jni.so
natives/linux-aarch64/libCore.so
natives/linux-aarch64/libdarraai_jni.so
加载顺序(NativeLoader):
- 系统属性
xyz.darra.ai.natives.dir指向的目录 - classpath 上
natives/<os>-<arch>/ java.library.path/System.loadLibrary("darraai_jni")(Core 先试DarraAI.Core,再试darraai_core)
环境要求
- 操作系统 — Windows x64、Linux x86_64、Linux aarch64(RK3588)。macOS / 32 位 / 其它架构由
NativeLoader抛AiException.UnsupportedPlatformException - Java — JDK 17
- native — 运行时需要
DarraAI.Core.dll+darraai_jni.dll(Linux 为libCore.so+libdarraai_jni.so)。缺库时加载失败,不放假二进制 - Windows 上指名
edge-rknn— Core 返回UNSUPPORTED_PLATFORM(RKNN 只在 linux-arm64)。Windows 收到 rknn 载荷返回UNSUPPORTED_PAYLOAD - 权限 — 装运行时包到系统目录时可能需要管理员;SDK 不代装 NVIDIA / RK3588 NPU 等系统驱动
- 不承诺 dump 免疫。 授权机 + 管理员级调试器在会话存活期暂停 dump,挡不住。本 SDK 防的是静态拷走、转发、无授权运行、常规 dump 工具、逆向授权算法。
- 加密单向。 官方不提供解回明文的通道。永久密码只用于无限次推理。公开包不能签发、不能加密。
- 环境提前部署。 SDK 只验证和加载本地 Provider;下载、安装与系统驱动由 Studio 或部署流程处理,
AiDiagnostics.collect提供只读诊断。 - macOS 不在 v1。 不是「即将支持」。
- 不承诺硬实时。 推理是阻塞调用。PLC 侧必须在扫描周期外进程 / 线程调用。
- 诊断 JSON 不含密钥 / 密码 / token / 机器指纹字节。
- Windows 无 RKNN。
edge-rknn永不出现在 Windows 安装列表。
功能概览
一模型一实例:一个 AiSession = 一份已加载模型 + 一个 Provider。多模型或多份同模型 = 多会话,API 完全相同。指名 Provider 不可用 = fail-closed,绝不静默降级。
| 功能 | 说明 |
|---|---|
| 会话 | AiSession.open / openPlain / openEx;try-with-resources |
| 推理 | inferImage + ImageDesc;每次一张图,循环帧 |
| 运行时 | 版本查询与本地环境诊断 |
| 版本与诊断 | AiDiagnostics.collect 去敏 JSON;禁止放进 PLC 扫描周期 |
| 错误处理 | 每个 darra_error_code 一个嵌套子类 |
| 类型 | PixelFormat / SessionOptions / NativeLoader |
String diag = AiDiagnostics.collect();
SessionOptions opt = SessionOptions.empty()
.intraOpThreads(4)
.parallel(2);
try (AiSession s = AiSession.openEx("model.darmodel", null, opt)) {
String json = s.inferImage(jpg, ImageDesc.encoded());
}
SDK 不发起环境下载,也没有安装进度回调。下载进度、取消与重试统一在 Studio 右上角下载中心处理,或由客户的部署流程负责。
| 类别 | 属性 | 类型 | 访问 | 说明 |
|---|---|---|---|---|
| 会话 | AiSession.open | AiSession | 静态 | 打开 .darmodel 建会话。不收激活码;未激活走 activate |
AiSession.openPlain | AiSession | 静态 | 打开明文模型建会话。与 open 同一推理路径,只跳过容器解码与验票。Paddle 是运行时载荷 | |
AiSession.openEx | AiSession | 静态 | 打开 .darmodel,带 SessionOptions 调度选项;options 为 null = Core 默认 | |
AiSession.metaJson | String | 方法 | 会话元信息 JSON。Java 侧拷贝,无需释放 | |
AiSession.inferImage | String | 方法 | 每次调用处理一张图,结果 JSON;相机/视频按帧循环调用。不承诺硬实时 | |
AiSession.close | void | 释放 | 关闭会话;NULL/重复关闭安全。禁止与在飞调用并发 | |
| 运行时 | AiRuntime.packedVersion | int | 查询 | 打包版本 major*65536 + minor*256 + patch |
AiRuntime.versionString | String | 查询 | 形如 1.0.0+runtime 的静态串 | |
AiDiagnostics.collect | String | 查询 | 本机环境诊断 JSON(去敏) | |
| 图像 | ImageDesc.auto | ImageDesc | 静态 | 编码字节流,按魔数自嗅探。裸缓冲禁止用 auto |
ImageDesc.encoded | ImageDesc | 静态 | 显式编码字节流;行为同 auto | |
ImageDesc.rgb888 | ImageDesc | 静态 | 裸 RGB888。stride=0 表示紧凑 | |
ImageDesc.bgr888 | ImageDesc | 静态 | 裸 BGR888(工业相机常见)。stride=0 表示紧凑 |
不同会话可并发。同一会话 inferImage 在 parallel 0/1 时内部互斥排队;同模型并发请设 SessionOptions.parallel = 2..8(走 openEx / openPlainEx),仍调 inferImage,一份权重。close() 禁止与任何在飞调用并发。
AiSession.openEx / openPlainEx 的 options 是调度选项 SessionOptions(线程 / 亲和 / GPU / 驻留 / 份额 / 并发份数)。激活码是 activate 的独立参数,keyPath 是 openWithKey 的独立参数,preferProvider 是各 open 入口的独立字符串参数。PixelFormat 只暴露 AUTO / ENCODED / RGB888 / BGR888。
快速开始
- 用 AI Studio 导出加密容器
.darmodel - 客户机安装
xyz.darra:darra-ai(须带对应平台 natives) - 代码中
AiSession.open→inferImage
import xyz.darra.ai.*;
// 先由 Studio 或部署人员准备所需 Provider。
try (AiSession session = AiSession.open("model.darmodel", null)) {
String meta = session.metaJson();
byte[] jpg = java.nio.file.Files.readAllBytes(java.nio.file.Path.of("photo.jpg"));
String json = session.inferImage(jpg, ImageDesc.auto());
}
对应包未部署时返回缺包错误,请先准备环境再重试。环境准备的进度在 Studio 右上角下载中心查看。
open 不收激活码:本机已绑机或本进程已 activate 过可直接开。未激活先 probe / activate(激活码是 activate 的独立参数);旧双文件 .darmkey 走 openWithKey。preferProvider 是各 open 入口的独立字符串参数,指名但不可用 = fail-closed,不静默降级。
失败时捕获对应子类,getHint() 即 error-catalog 给最终用户的修复建议:
try {
// Open / InferImage
} catch (AiException ex) {
System.err.println(ex.getMessage());
System.err.println(ex.getHint());
}
明文模型
与加密入口同一推理路径,只跳过容器解码与验票。Paddle 是运行时载荷:明文路径可接 .pdmodel(同目录须有 .pdiparams)或含二者的目录。
try (AiSession session = AiSession.openPlain("model.onnx", null)) {
byte[] jpg = java.nio.file.Files.readAllBytes(java.nio.file.Path.of("photo.jpg"));
String json = session.inferImage(jpg, ImageDesc.encoded());
}
openPlain 的路径可以是 .onnx、.pdmodel(同目录须有 .pdiparams)、或含二者的目录。.pt / .pth 抛 AiException.UnsupportedPayloadException。第二参是 preferProvider;null = 按载荷 × 硬件 × 已装包自动选。
.darmodel+ 授权 — 生产环境,推荐。openPlain— Studio 试跑 / 客户自有明文模型。
工业相机裸缓冲
每次调用处理一张图。相机连续采集时按帧循环调用。裸缓冲禁止 ImageDesc.auto()(嗅探不出通道序)。stride = 0 表示紧凑(= width × 3)。
byte[] frame = grabBgrFrame();
String results = session.inferImage(
frame, ImageDesc.bgr888(1920, 1080, 0));
版本兼容
当前 Java SDK v1.0.0。绑定与 DarraAI.Core 必须同一发布批次;major 变 = ABI 破坏,须成套升级。公开包是 runtime 构建,客户机 versionString() 必须看到 +runtime。