跳到主要内容

Java SDK 概述

xyz.darra:darra-ai 是对 darra_ai.h 的 JNI 薄封装:只翻译类型和错误码,不另造语义,零密码学。权威契约 = Core/include/darra_ai.h;hint 文案与 错误码目录 逐字一致。版本 1.0.0AiRuntime.VERSION_MAJOR/MINOR/PATCH,与头文件 DARRA_VERSION_* 对齐)。

主 jar 纯 Java,不内嵌 dll/so。native(DarraAI.Core + darraai_jni)按 classifier 另打。

命名风格

包名 xyz.darra.ai。方法 camelCaseopenPlain / inferImage / ensureCancel)。错误是 AiException 的嵌套子类:AiException.IoNotFoundException。会话实现 AutoCloseable,用 try-with-resources。

安装

<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。authoring 风味(仅 AI Studio)为 natives-<os>-<arch>-authoring

包坐标与仓内既有 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)。

环境要求

  • 操作系统 — Windows x64、Linux x86_64、Linux aarch64(RK3588)。macOS / 32 位 / 其它架构由 NativeLoaderAiException.UnsupportedPlatformException
  • Java — JDK 17
  • native — 运行时需要 DarraAI.Core.dll + darraai_jni.dll(Linux 为 libdarraai_core.so + libdarraai_jni.so)。缺库时加载失败,不放假二进制
  • Windows 上指名 edge-rknn — Core 返回 UNSUPPORTED_PLATFORM(RKNN 只在 linux-arm64)

加载后核 ABI:darra_version() 的 major 必须等于 NativeLoader.HEADER_MAJOR(1),否则拒绝继续。

快速开始

明文 ONNX(Studio 试跑 / 客户自有未加密模型):

import xyz.darra.ai.*;

AiRuntime.ensure("cpu-only", null, (percent, stage) ->
System.out.printf("[%s] %.1f%%%n", stage, percent));

try (AiSession session = AiSession.openPlain("model.onnx", "onnx-cpu")) {
String meta = session.metaJson();
byte[] jpg = java.nio.file.Files.readAllBytes(java.nio.file.Path.of("a.jpg"));
String json = session.inferImage(jpg, ImageDesc.auto());
}

openPlain 的第二参是 preferProvidernull = 按载荷 × 硬件 × 已装包自动选。训练格式(.pt / .pth / Paddle)抛 AiException.UnsupportedPayloadException

加密容器

keypassword 至少给一个;都给则 key 文件优先验票。preferProvider 指名但不可用 = fail-closed,不静默降级。

try (AiSession s = AiSession.open("model.darmodel", "model.darmkey", null, null)) {
String json = s.inferImage(pixels, ImageDesc.rgb888(640, 480));
}

也可走可扩展入口(当前翻译到 open;Core 落地 darra_session_open_ex 后只换调用点):

SessionOptions opt = SessionOptions.empty()
.keyPath("model.darmkey")
.preferProvider(null);
try (AiSession s = AiSession.openEx("model.darmodel", opt)) {
String json = s.inferImage(jpg, ImageDesc.encoded());
}

工业相机裸缓冲

裸缓冲禁止 ImageDesc.auto()(嗅探不出通道序)。stride = 0 表示紧凑(= width × 3)。

byte[] frame = grabBgrFrame(); // 调用方自己的采集
String results = session.inferImage(
frame, ImageDesc.bgr888(1920, 1080, 0));

诊断与取消

诊断可能触发 WMI / NVML / sysfs,耗时可到数百毫秒,禁止放进 PLC 扫描周期。推理不承诺硬实时。

String diag = AiDiagnostics.collect();

取消在飞的 ensure:任意线程可调(含 UI 线程);进度回调内禁止再调任何本 SDK 方法(含 ensureCancel)。没有在飞的 ensure 时为 no-op。失败/取消不留半成品。

AiRuntime.ensureCancel();

进度回调在 SDK 工作线程触发:percent 0..100,stageprobe / manifest / download / verify / install / done。只准记录或转发到自己的 UI 队列。

类一览

类型作用
AiRuntimeensure / ensureCancel / packedVersion / versionString。对应 darra_runtime_ensure / darra_version
AiSession推理会话(AutoCloseable):open / openPlain / openEx / metaJson / inferImage / close
ImageDescauto / encoded / rgb888 / bgr888。对应 darra_image_desc
PixelFormatAUTO(0) / ENCODED(1) / RGB888(2) / BGR888(3),与 darra_image_format 逐值对齐
SessionOptionskeyPath / password / preferProvider;构造不加载 native
AiDiagnosticscollect() — 环境自检 JSON(去敏,不含密钥/密码/token/机器指纹字节)
AiException每个 darra_error_code(除 OK)一个嵌套子类
NativeLoader加载 JNI + Core;runtimeClassifier() / authoringClassifier()
xyz.darra.ai.authoring.Authoring仅 authoring natives:encryptOnnx / issueKey / fingerprintPerturb

AiSession 从 meta JSON 抽出的只读字段:task() / labels() / inputWidth() / inputHeight() / channels() / layout() / payloadKind() / providerId() / encrypted()。缺席时字符串为 null、标签为空列表、宽高通道为 0。

不同会话可并发;同一会话 inferImage 允许多线程并发(吞吐扩展仍推荐每线程一个会话)。close() 禁止与任何在飞调用并发;关闭后句柄失效。NULL/重复 close 安全。

Provider / profile ID

AiRuntime.ensure 合法 ID(源码注释):

  • 细包:onnx-cpu / onnx-cuda / onnx-openvino / onnx-trt-ep / trt-native / edge-rknn(仅 linux-arm64)
  • 场景整合包:cpu-only / nvidia-gpu / intel-iap / amd-dml / board-rk3588
  • null = 按硬件探测自动选细包

ensure 幂等;进程内串行。offlineZip 为离线整合包 zip 路径;null = 在线下载。

natives classifier

classifier内容使用场景
natives-windows-x86_64DarraAI.Core.dll + darraai_jni.dllWindows x64 runtime
natives-linux-x86_64libdarraai_core.so + libdarraai_jni.soLinux x64 runtime
natives-linux-aarch64同上 soLinux ARM64 / RK3588 runtime
natives-<os>-<arch>-authoringauthoring 风味 Core + JNI(定义 DARRA_AUTHORING仅 AI Studio

classifier jar 内资源路径(NativeLoader 从 classpath 抽出):

natives/windows-x86_64/DarraAI.Core.dll
natives/windows-x86_64/darraai_jni.dll
natives/linux-x86_64/libdarraai_core.so
natives/linux-x86_64/libdarraai_jni.so
natives/linux-aarch64/libdarraai_core.so
natives/linux-aarch64/libdarraai_jni.so

加载顺序(NativeLoader):

  1. 系统属性 xyz.darra.ai.natives.dir 指向的目录
  2. classpath 上 natives/<os>-<arch>/
  3. java.library.path / System.loadLibrary("darraai_jni")(Core 先试 DarraAI.Core,再试 darraai_core

错误处理

失败时 JNI 调 darra_last_error,再 AiException.throwByCode。hint 原文透传,不改写。getCode() / getMessage() / getHint() 分别对应 C 的 code / message / hint。未知码抛基类,不丢信息。code == 0 为 no-op。

try {
// Open / InferImage
} catch (AiException ex) {
System.err.println(ex.getMessage()); // C 的 message
System.err.println(ex.getHint()); // error-catalog 给最终用户的修复建议
}
C 常量Java 异常
1DARRA_IO_NOT_FOUNDAiException.IoNotFoundException
2DARRA_IO_DENIEDAiException.IoDeniedException
3DARRA_BAD_CONTAINERAiException.BadContainerException
4DARRA_BAD_LICENSEAiException.BadLicenseException
5DARRA_PASSWORD_REQUIREDAiException.PasswordRequiredException
6DARRA_PASSWORD_WRONGAiException.PasswordWrongException
7DARRA_MACHINE_MISMATCHAiException.MachineMismatchException
8DARRA_TRIAL_EXHAUSTEDAiException.TrialExhaustedException
9DARRA_UNSUPPORTED_PAYLOADAiException.UnsupportedPayloadException
10DARRA_UNSUPPORTED_PLATFORMAiException.UnsupportedPlatformException
11DARRA_PROVIDER_MISSINGAiException.ProviderMissingException
12DARRA_PROVIDER_ABI_MISMATCHAiException.ProviderAbiMismatchException
13DARRA_HARDWARE_MISSINGAiException.HardwareMissingException
14DARRA_DRIVER_TOO_OLDAiException.DriverTooOldException
15DARRA_NETWORK_FAILEDAiException.NetworkFailedException
16DARRA_CHECKSUM_MISMATCHAiException.ChecksumMismatchException
17DARRA_CANCELLEDAiException.CancelledException
18DARRA_INTERNALAiException.InternalException

参数契约违反(空路径 / 空 imageBytes / 空 desc / 裸缓冲宽高 ≤ 0 / 会话已关闭)归 InternalException。逐码含义见 错误码目录

authoring

xyz.darra.ai.authoring.Authoring 只在 authoring natives 上真正转发 darra_encrypt_onnx / darra_issue_key / darra_fingerprint_perturb。runtime JNI 未定义 DARRA_AUTHORING,调用抛 InternalException:「当前为 runtime 构建,authoring API 物理上不存在(仅 AI Studio 安装包导出)」。Java 侧仍然零密码学。

请使用 NativeLoader.authoringClassifier() 对应的 natives 包。调用顺序:扰动 → 加密 → 签发。

import xyz.darra.ai.authoring.Authoring;

Authoring.fingerprintPerturb("model.onnx", "model.perturbed.onnx", customerSeed);
Authoring.encryptOnnx("model.perturbed.onnx", "model.darmodel");
Authoring.issueKey("model.darmodel", password, "model.darmkey"); // 默认不绑机、永久授权
// 绑机 / 试用计次:issueKey(container, password, outKey, bindMachine, trialRuns)

issueKeytrialRuns:0 = 永久授权;>0 = 试用计次。passwordnull = 本授权不启用密码。

编译 JNI 桥

仓库路径 Darra.AI.Studio.SDK/Java/darra-ai/src/main/cpp/jni_bridge.c。Windows(JDK include + Core 头):

cl /W4 /utf-8 /c ^
/I "%JAVA_HOME%\include" /I "%JAVA_HOME%\include\win32" ^
/I ..\..\..\Core\include ^
jni_bridge.c

链接时再链 DarraAI.Core.lib,产出 darraai_jni.dll。Linux:

cc -Wall -Wextra -fPIC -c \
-I "${JAVA_HOME}/include" -I "${JAVA_HOME}/include/linux" \
-I ../../../Core/include \
jni_bridge.c

authoring 风味加 -DDARRA_AUTHORING