跳到正文
LICENTIVO / INTEGRATION

Java 软件授权接入:激活、验证与导出功能保护

在 Java 17+ 应用中激活客户授权码并保护实际导出。保留一个客户端,由 SDK 管理设备凭据、心跳及许可的离线使用。

Java 17+更新日期

1. 准备产品与许可证

先使用设备绑定许可证和普通导出功能,确认授权流程正常后再增加功能次数计量。

设备额度按当前激活设备计算,释放后返还;普通授权离线仍占用,浮动授权租约到期后自动返还。

  1. 在控制台“产品”复制产品 ID,点击同一产品的“签名公钥”,将每一组密钥 ID、公钥填进初始化代码,替换 YOUR_PRODUCT_ID、YOUR_KEY_ID 和 YOUR_PUBLIC_KEY。快速接入也可以直接复制已填好的代码。无需配置文件;SDK 默认连接 https://www.licentivo.com。
  2. 在「快速接入」创建或选择产品,在策略中启用名为 export 的功能,并准备测试许可证。

2. 安装 SDK

此版本正在完成发布验证。

3. 保护一次实际导出

将 SDK 初始化接到自己软件的启动或激活入口,从激活窗口读取客户授权码,传入自己的产品 ID、受信公钥并保持客户端存活。把 RunFeature 放在真实业务入口,将导出示例函数替换成自己的实际功能。

Java · Quickstart.java
import licentivo.Client;

import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Map;

/** A single protected operation. Keep Client alive while your application runs. */
public final class Quickstart {
// BEGIN LICENTIVO PRODUCT
// Copy Product ID and all key ID/public key pairs from Console > Products > Signing public keys.
private static final String PRODUCT_ID = "YOUR_PRODUCT_ID";
private static final Map<String,String> TRUSTED_KEYS = Map.of("YOUR_KEY_ID", "YOUR_PUBLIC_KEY");
// END LICENTIVO PRODUCT

    private static String setting(String name, String fallback) {
        String value = System.getenv(name);
        return value == null || value.isEmpty() ? fallback : value;
    }

    static void exportReport(String path) throws Exception {
        // Replace this write with your existing, non-metered export operation.
        Files.writeString(Path.of(path), "A report generated by the licensed application.\n");
    }

    public static void main(String[] args) {
        // In a GUI, read the activation input. Later starts pass an empty key.
        try (var client = Client.openProduct(PRODUCT_ID, TRUSTED_KEYS,
                setting("LICENTIVO_LICENSE_KEY", ""), error -> System.err.println("Background verification: " + error.getMessage()))) {
            String feature = setting("LICENTIVO_FEATURE", "export");
            String path = setting("LICENTIVO_OUTPUT", "licensed-report.txt");
            if (setting("LICENTIVO_METERED", "").equals("1"))
                client.runMeteredFeature(feature, 1, setting("LICENTIVO_OPERATION_ID", ""), () -> exportReport(path));
            else
                client.runFeature(feature, () -> exportReport(path));
            System.out.println("License OK: " + feature + " is available\nExport completed: " + path);
        } catch (Exception error) {
            System.err.println(error.getMessage());
            System.exit(2);
        }
    }
}

4. 在应用退出时关闭客户端

本命令行示例执行一次操作后退出。接入桌面应用时,在启动时创建一个客户端,在导出按钮或命令中调用功能回调,直到应用退出才关闭客户端。

首次激活后,后续启动可将 LICENTIVO_LICENSE_KEY 留空,在相同用户及缓存位置恢复私有设备凭据。凭据保存在用户应用数据目录,不随安装包分发。关闭客户端会停止心跳并归还浮动席位;普通退出不应注销设备绑定。

只有策略允许、签名授权仍有效时才能离线使用。许可证过期或功能被拒绝时继续阻止业务操作;功能次数计量需要联网。

Swing 或 JavaFX 应用应在后台线程处理启动验证,再把后台通知切回界面线程。让 Client 的生命周期覆盖窗口,退出时由 try-with-resources 关闭。

5. 运行并核对结果

在控制台“产品”复制产品 ID,点击同一产品的“签名公钥”,将每一组密钥 ID、公钥填进初始化代码,替换 YOUR_PRODUCT_ID、YOUR_KEY_ID 和 YOUR_PUBLIC_KEY。快速接入也可以直接复制已填好的代码。无需配置文件;SDK 默认连接 https://www.licentivo.com。

  1. 使用允许 export 的有效许可证运行,确认生成 licensed-report.txt。
  2. 清空 LICENTIVO_LICENSE_KEY,以相同用户再次运行,确认可恢复已保存的设备凭据。
  3. 把 LICENTIVO_FEATURE 改为许可证没有的功能,并将 LICENTIVO_OUTPUT 改为新文件名。程序应提示拒绝,且不生成新文件。
  4. 仅在策略允许且签名授权未到期时测试离线重启。后台刷新报错后,也不能绕过失败的功能检查。
Windows · PowerShell
javac -cp licentivo-sdk-0.11.6.jar -d out Quickstart.java
$env:LICENTIVO_LICENSE_KEY = 'YOUR_LICENSE_KEY'
java -cp "out;licentivo-sdk-0.11.6.jar" Quickstart
Linux / macOS · Bash
javac -cp licentivo-sdk-0.11.6.jar -d out Quickstart.java
LICENTIVO_LICENSE_KEY=YOUR_LICENSE_KEY java -cp "out:licentivo-sdk-0.11.6.jar" Quickstart

常见接入问题

检查产品 ID、每组密钥 ID 和公钥、客户输入的授权码。公钥属于产品;客户许可证和本机凭证分别管理。开发测试授权码和厂商管理 API Key 不进入客户安装包。

功能被拒绝、设备数已满或许可证过期:在控制台核对许可证及策略,并向客户显示 SDK 错误。授权失败时不能调用导出函数。

普通功能接口只检查权限;计次接口负责预留和结算已配置的用量。每项真实业务使用独立且稳定的操作编号;中断恢复前先核对持久化业务结果。

找不到类:运行 classpath 同时包含 out 和 SDK JAR。Windows 用分号分隔,Linux 与 macOS 用冒号分隔。