feat(sdk): add JNA bridge to replace JNI for Rust C ABI access

This commit is contained in:
2026-05-25 15:15:14 +08:00
parent f82a2a7b24
commit 027ecbd375
4 changed files with 151 additions and 0 deletions
@@ -0,0 +1,53 @@
package cn.craftlabs.auth.internal;
import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.Structure;
import java.util.Arrays;
import java.util.List;
public interface CraftCoreLibrary extends Library {
CraftCoreLibrary INSTANCE = Native.load("craftlabs_auth_core", CraftCoreLibrary.class);
class CraftResult extends Structure {
public int success;
public String message;
@Override
protected List<String> getFieldOrder() {
return Arrays.asList("success", "message");
}
}
class LicenseInfoStruct extends Structure {
public int isLicensed;
public long expirationDate;
public Pointer featureNames;
public Pointer featureValues;
public int featureCount;
@Override
protected List<String> getFieldOrder() {
return Arrays.asList("isLicensed", "expirationDate", "featureNames", "featureValues", "featureCount");
}
}
Pointer craft_initialize(String configJson);
void craft_destroy(Pointer handle);
CraftResult craft_activate(Pointer handle, String licenseKey);
CraftResult craft_check_license(Pointer handle);
LicenseInfoStruct craft_get_license_info(Pointer handle);
void craft_free_license_info(LicenseInfoStruct info);
int craft_has_feature(Pointer handle, String featureName);
CraftResult craft_release(Pointer handle);
CraftResult craft_heartbeat(Pointer handle);
}
@@ -0,0 +1,89 @@
package cn.craftlabs.auth.internal;
import cn.craftlabs.auth.AuthProvider;
import cn.craftlabs.auth.AuthResult;
import cn.craftlabs.auth.LicenseInfo;
import com.sun.jna.Native;
import com.sun.jna.Pointer;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
public class JnaAuthProvider implements AuthProvider {
private Pointer nativeHandle;
@Override
public AuthResult initialize(String configJson) {
if (nativeHandle != null) {
CraftCoreLibrary.INSTANCE.craft_destroy(nativeHandle);
}
nativeHandle = CraftCoreLibrary.INSTANCE.craft_initialize(
configJson != null ? configJson : "{}");
return new AuthResult(nativeHandle != null, "Initialized");
}
@Override
public AuthResult activate(String licenseKey) {
CraftCoreLibrary.CraftResult r = CraftCoreLibrary.INSTANCE.craft_activate(
nativeHandle, licenseKey);
return new AuthResult(r.success != 0, r.message);
}
@Override
public AuthResult checkLicense() {
CraftCoreLibrary.CraftResult r = CraftCoreLibrary.INSTANCE.craft_check_license(nativeHandle);
return new AuthResult(r.success != 0, r.message);
}
@Override
public LicenseInfo getLicenseInfo() {
CraftCoreLibrary.LicenseInfoStruct s = CraftCoreLibrary.INSTANCE.craft_get_license_info(nativeHandle);
if (s == null) {
return new LicenseInfo(false, null, null);
}
Map<String, Boolean> features = null;
if (s.featureCount > 0 && s.featureNames != null) {
features = new HashMap<>(s.featureCount);
for (int i = 0; i < s.featureCount; i++) {
Pointer namePtr = s.featureNames.getPointer((long) i * Native.POINTER_SIZE);
String name = namePtr != null ? namePtr.getString(0) : null;
if (name != null) {
int val = s.featureValues != null
? s.featureValues.getInt((long) i * Integer.BYTES)
: 0;
features.put(name, val != 0);
}
}
}
Date expirationDate = s.expirationDate > 0 ? new Date(s.expirationDate) : null;
CraftCoreLibrary.INSTANCE.craft_free_license_info(s);
return new LicenseInfo(s.isLicensed != 0, expirationDate, features);
}
@Override
public boolean hasFeature(String featureName) {
return CraftCoreLibrary.INSTANCE.craft_has_feature(nativeHandle, featureName) != 0;
}
@Override
public AuthResult release() {
CraftCoreLibrary.CraftResult r = CraftCoreLibrary.INSTANCE.craft_release(nativeHandle);
return new AuthResult(r.success != 0, r.message);
}
@Override
public AuthResult heartbeat() {
CraftCoreLibrary.CraftResult r = CraftCoreLibrary.INSTANCE.craft_heartbeat(nativeHandle);
return new AuthResult(r.success != 0, r.message);
}
@Override
public void close() {
if (nativeHandle != null) {
CraftCoreLibrary.INSTANCE.craft_destroy(nativeHandle);
nativeHandle = null;
}
}
}