Java binds through JNA, so there is no JNI layer for you to compile and no per-platform native build in your own project — the SDK ships the native libraries and JNA loads the right one.
<dependency>
<groupId>com.keynub</groupId>
<artifactId>keynub-licdongle</artifactId>
<version>1.1.1</version>
</dependency>Code language: HTML, XML (xml)
Reading a License
try (LicenseDongleContext ctx = new LicenseDongleContext();
Dongle dongle = ctx.open()) { // first dongle found
dongle.verifyGenuine(); // throws unless genuine
try (Session session = dongle.openSession()) {
byte[] license = session.readRecord("license");
}
}Code language: Java (java)
Dongle implements AutoCloseable, so try-with-resources closes the device on every path out of the block.
Why Java Needs the Data-Gating Pattern Badly
Java bytecode decompiles almost perfectly. A licence check written as if (licensed) is visible in any decompiler and removable with a bytecode editor in minutes, and obfuscators only raise the effort. This is not a Java weakness so much as a reason not to rely on a branch at all.
And the rule that matters in every language: do not branch on a boolean. Encrypt data your program needs with appEncrypt at build time and decrypt it through the dongle at run time, so removing the check leaves the program with nothing to compute rather than a working unlicensed copy.
Resources and Error Handling
The context, the dongle and the session all implement AutoCloseable, so try-with-resources closes them in the right order and a session cannot quietly outlive the device it came from. Failures arrive as an exception carrying the numeric status from the C ABI, with subclasses for the cases worth catching separately, so you are not comparing integers by hand.
The binding is a thin JNA wrapper: no protocol parsing and no cryptography in Java, all of that in the same native core every other binding uses. Java 17 or later, on Windows, Linux and macOS, with no driver to install.
Shipping the Native Library with a Java Application
The com.keynub:keynub-licdongle artifact on Maven Central holds the binding’s classes; the native library ships beside the application. JNA loads keynub_licdongle for the platform from jna.library.path or the system search path, or from the file that -Dkeynub.licdongle.library=<path> names, so a fat JAR, a jlink image or a jpackage installer takes the library file along and names it with that property. The prebuilt libraries for every platform are in the SDK repository’s natives/<platform>/ folder, with a SHA-256 manifest: Windows x64, x86 and ARM64, Linux x86_64 and aarch64, and universal macOS binaries for Intel and Apple silicon.
To use a library from somewhere else, set -Dkeynub.licdongle.library=<path>, or put it on jna.library.path. On Linux, install the udev rule from NATIVES.md once, so that ordinary users may open the device.
Questions Java Developers Ask
Which Java Versions Does the Binding Support?
Java 17 and later. The binding uses JNA, so there is no JNI library to compile, and Kotlin, Scala and Groovy use it unchanged.
Can a Hardware Dongle Protect Java Bytecode That Decompiles so Easily?
That is exactly the case it is for. Bytecode decompiles to readable source and an obfuscator only slows the reader down, so a licence check written as a branch is found and removed. Put data the program needs through the dongle’s app-data encryption instead; a decompiler then shows a call that produces nothing without the dongle.
Does a Java Application Need Administrator Rights to Talk to the Dongle?
No, and no driver either: the dongle is a USB HID device that the operating systems handle with their built-in class drivers. On Linux, install the shipped udev rule once so that ordinary users may open it; without the rule the SDK reports access denied and names the cause in its error detail.
Can Several Dongles Be Connected at Once?
Yes. The SDK enumerates every attached dongle with its serial number and device path, and you open one by serial; with no serial given, the first dongle found is used.
Does a Java License Check Need an Internet Connection?
No. Verification is a local exchange between your program and the dongle over USB: the SDK checks the dongle’s certificate chain to KeyNub’s root and runs a live challenge-response. There is no activation server and no account, so the check works on air-gapped machines.
Can a License Written from Java Be Read by a Program in Another Language?
Yes. Every binding drives the same core library and the same dongle, and records and sealed data are language-neutral bytes. Your issuing tool can be written in one language and your product in another.
Code
Runnable sample: java/VerifyAndRead.java. Binding source: bindings/java. Both are Apache-2.0, in the public SDK repository; the prebuilt native libraries are in the repository’s natives/ folder, one per platform.
All supported languages · All industries · Buy a KeyNub · Ask us something