Class encryption
Everything else makes your bytecode hard to read. ClassGuard removes it from disk entirely: your classes ship as encrypted blobs with no loadable bytecode to decompile, unsealed only in memory, only at load time. It's the strongest single option in Lock Master.
What it does
With classGuard on, each of your classes is encrypted with strong authenticated encryption and the original .class file is stripped from the jar. In its place ships an opaque encrypted blob. A tiny generated bootstrap loader — the only real bytecode left — reconstructs the key at runtime and unseals each class on demand, in memory. Nothing decrypted ever touches the disk.
{ "classGuard": { "enabled": true, "mode": "STANDALONE" } }The result: a decompiler opening your jar finds almost nothing to work with. No class names, no methods, no strings — just ciphertext and a loader.
Before & after
Real output. A six-class jar, before and after ClassGuard. Every business class is gone from the file listing — replaced by encrypted .bin blobs underMETA-INF/guardian/ — and only the two-class bootstrap loader remains as openable bytecode:
demo/Heavy.class
demo/Report.class
demo/Sample.class
shop/App.class
shop/model/Cart.class
shop/util/Money.class
a/a.class
b/b.class
META-INF/guardian/-4512027295375453326.bin
META-INF/guardian/5166365122521541383.bin
META-INF/guardian/-5206015750035504180.bin
META-INF/guardian/-5405373286271541278.bin
META-INF/guardian/6344447860271584778.bin
META-INF/guardian/7602776200188678415.bin
The .bin files are high-entropy ciphertext — no readable strings, no class structure, nothing a decompiler can parse. Your Sample,Report, Cart and the rest simply aren't there as bytecode any more. To read them, an attacker has to defeat the encryption and capture the classes as the JVM unseals them at runtime — which is the path antiDebug closes.
Modes & fields
ClassGuard needs an entry point where it can unseal your classes before anything uses them. That's the only real decision: where your program starts.
| Field | What it does |
|---|---|
| enabled | Turn on whole-class encryption. |
| mode | STANDALONE — for normal apps: a generated launcher class becomes the main entry point and unseals everything on startup. PLUGIN — for Minecraft plugins (Bukkit / Spigot / Paper): it patches your plugin's onLoad()/onEnable() to unseal at load, since the server owns the launch. |
| pluginMainClass | Required for PLUGIN mode. The internal name of your plugin's main class. |
| excludeClasses | Classes or prefixes to leave unencrypted — your entry point, and anything loaded very early or by name before the loader is ready. |
PLUGIN mode your main class must be set as pluginMainClass, added to excludeClasses, andkept from renaming — the server looks it up by the name in your plugin.yml.antiDebug
Sealing the classes closes static analysis, so the remaining attack is dynamic: run the program under a debugger and dump the classes as they're unsealed. antiDebug closes that door. At a ClassGuard entry point it inspects the JVM's launch configuration and, if a debugger is attached, refuses — so the encrypted classes are never unsealed under observation.
| Field | What it does |
|---|---|
| enabled | Turn it on. Needs ClassGuard to have an entry point. |
| action | "throw" — refuse to unseal (fail to enable/load). "exit" — kill the JVM outright. |
| checkAgents | Also flag -javaagent / -agentpath. Off by default — many legitimate servers run monitoring or profiling agents, so only enable it if yours doesn't. |
watermark
An invisible, recoverable identifier stamped redundantly across your jar, so a leaked copy traces back to the exact license it was issued under. It's split and checksummed across classes, so it survives re-jarring or partial deletion, and reading it back needs a vendor secret that never ships in the build.
Before you ship
- Test on a real run. ClassGuard changes how your program loads — always run the sealed build on a real server or launch before shipping.
- It's non-reproducible by design. The encryption key is drawn from a secure random source, so a ClassGuard build differs every time even with a fixed seed. That's deliberate — a reproducible key would defeat the purpose.
- Mind the entry point. Keep whatever starts your program (or is loaded before the loader runs) in
excludeClasses.