Scala reaches the dongle through keynub.licdongle, a Scala 3 library over the SDK’s Java binding (JNA): results are case classes and vectors, failures are a LicDongleError with a Status, and withDongle and withSession close what they open on every exit path. The com.keynub:keynub-licdongle-scala_3 artifact on Maven Central, Scala 3.3 or later on Java 17 or later, on Windows, Linux and macOS.
// sbt
libraryDependencies += "com.keynub" %% "keynub-licdongle-scala" % "1.1.1"
// Mill
mvn"com.keynub::keynub-licdongle-scala:1.1.1"
// scala-cli
//> using dep com.keynub::keynub-licdongle-scala:1.1.1Code language: Scala (scala)
Reading a License
import keynub.licdongle.*
val license = LicDongle.withDongle { dongle => // first dongle, or withDongle(serial) { ... }
dongle.verifyGenuine() // throws unless genuine
dongle.withSession { session => // closed on every exit path
session.readString("license")
}
}Code language: Scala (scala)
What You Are Protecting
Scala software that is sold usually runs on the JVM as an assembly JAR: a data platform component, an analysis tool, a server product installed on the customer’s machines. Its classes decompile readily, and a check that returns a Boolean is one if to remove.
So the strong pattern is the one to reach for: the data the program needs only exists when the dongle is present.
// Weak: one removed branch.
if !dongle.isGenuine then sys.exit(1)
// Strong: the parameters only exist with the dongle present.
val parameters = dongle.withSession { session =>
decodeParameters(session.appDecrypt(sealedBlobShippedWithYourProgram))
}Code language: Scala (scala)
Every failure the native library reports is a LicDongleError with status (Status.NoDevice, Status.NotGenuine, Status.AuthRequired, …), the numeric code and the library’s detail, with the Java exception as its cause; isGenuine fails closed. Record data, keys and sealed data are Array[Byte], and the methods that take data also take a String, used as its UTF-8 bytes.
Shipping the Native Library with a Scala Application
The library, like the Java binding it builds on, carries no native library: an assembly JAR ships keynub_licdongle for its platform with it. In a clone of the SDK repository the library finds it in natives/<platform>/ from the working directory upwards; elsewhere it takes one on the JNA search path (jna.library.path, PATH, LD_LIBRARY_PATH, DYLD_LIBRARY_PATH), or the one that LicDongle.setLibraryPath, KEYNUB_LICDONGLE_LIBRARY or the system property keynub.licdongle.library names.
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. On Linux, install the udev rule from NATIVES.md once, so that ordinary users may open the device.
Questions Scala Developers Ask
Which Scala Versions Does the Library Support?
Scala 3.3 and later on Java 17 and later, on Windows, Linux and macOS. The artifact is keynub-licdongle-scala_3, which sbt’s %% and Mill’s :: select.
Does the Scala Library Work with Sbt, Mill and Scala-Cli?
All three: it is an ordinary library on Maven Central, com.keynub:keynub-licdongle-scala_3, and pulls in the Java binding com.keynub:keynub-licdongle. The samples in the repository run with scala-cli.
Does a Scala 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.
Does a Scala 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.
Who Can Read the License Records on a Dongle?
Anyone holding the dongle: a program opens a session and reads records, and can decrypt data sealed for that dongle. Writing records, erasing them and incrementing counters need your write key. What the dongle guarantees is that none of it is available without the dongle present.
Can a License Written from Scala 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: scala/VerifyAndRead.scala. Binding source: bindings/scala. 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