Java SDK
Java SDK
Pure Java 11+. Uses Java's built-in HttpClient — no Apache HttpClient or OkHttp required.
JSON handled by Jackson (pulled automatically by Maven).
Installation
The published package is dev.permitcore:permitcore-sdk:1.0.0. Add the dependency below to use Maven Central. To build from the optional source ZIP instead:
cd SDKs/java mvn install
Then add to your pom.xml:
<dependency> <groupId>dev.permitcore</groupId> <artifactId>permitcore-sdk</artifactId> <version>1.0.0</version> </dependency>
Quick start
import dev.permitcore.PermitClient; PermitClient client = new PermitClient("https://api.permitcore.dev"); PermitClient.ValidateResult result = client.validate("PERMIT-XXXX-XXXX-XXXX-XXXX"); if (result.isValid) { System.out.println("License OK — product: " + result.productName); // Unlock features if (result.features != null && result.features.contains("export")) enableExportMenu(); if (result.isTrial) showTrialBanner(result.trialDaysRemaining + " days remaining"); if (result.isOffline) System.out.println("Running on a cached result — server was unreachable."); } else { showLicenseError(result.message); }
validate() and activate() never throw for a network failure — they fall back to the local offline-grace cache automatically and, failing that, return isValid: false with isOffline: true. Only meter() throws PermitException.
Validate with version check
PermitClient.ValidateResult result = client.validate("PERMIT-XXXX-XXXX-XXXX-XXXX", "2.3.1"); if (!result.isValid && result.minVersion != null) showError("Please upgrade to v" + result.minVersion + " or newer.");
Activation
var req = new PermitClient.ActivateRequest( "PERMIT-XXXX-XXXX-XXXX-XXXX", "sha256-of-hardware-fingerprint", // deviceId InetAddress.getLocalHost().getHostName(), // deviceName "2.3.1" // version ); PermitClient.ValidateResult result = client.activate(req); if (result.isValid) saveActivationSuccess();
Metered billing
// Single event PermitClient.MeterResult m = client.meter("PERMIT-XXXX-XXXX-XXXX-XXXX", "export"); // Batch — 5 API calls at once var req = new PermitClient.MeterRequest("PERMIT-XXXX-XXXX-XXXX-XXXX", "api_call", 5, null); PermitClient.MeterResult m = client.meter(req);
ValidateResult field reference
| Field | Type | Description |
|---|---|---|
isValid | boolean | true if the license is active and all checks pass |
productName | String | Name of the product this license belongs to |
remainingActivations | Integer | How many more activations are allowed (null = unlimited) |
expiresAt | OffsetDateTime | License expiry in UTC (null = perpetual) |
message | String | Human-readable status message |
customFields | Map<String, String> | Arbitrary key/value metadata set by the vendor on this license |
vendorWarning | String | Non-null if the vendor's PermitCore subscription is lapsing — display a warning to your user |
features | List<String> | Feature flags enabled on this license (e.g. ["export","api","premium"]) |
isTrial | boolean | true if this is a trial license |
trialDaysRemaining | Integer | Days remaining in the trial (0 when not a trial) |
nodeLocked | boolean | true if this license uses HWID node-locking |
offlineGraceDays | Integer | Days the software may run without reaching the server |
minVersion | String | Minimum allowed software version (semver), null if unrestricted |
maxVersion | String | Maximum allowed software version (semver), null if unrestricted |
isOffline | boolean | true when this result was served from the local offline-grace cache (server unreachable) |
Offline grace period (built in)
When offlineGraceDays is set on the license, validate()/activate() cache every successful result to the OS temp directory (java.io.tmpdir). If a later call can't reach the server, the cached result is returned automatically — check isOffline to detect it. Disable with new PermitClient(baseUrl, false).
Error handling
validate() and activate() never throw for a network failure — they fall back to the cache and, failing that, return isValid: false with message: "Cannot reach license server." and isOffline: true. Only meter() throws PermitClient.PermitException (checked exception) on a network error, timeout, or HTTP 429 (rate limited) — usage events aren't cached, since replaying a stale count on reconnect could double-count.
var result = client.validate(key); if (result.isValid) { // proceed — result.isOffline tells you if this came from cache } else { showLicenseDialog(result.message); // key expired, revoked, or unreachable } try { client.meter(key, "export"); } catch (PermitClient.PermitException e) { log.warn("Could not record usage event: " + e.getMessage()); }