Every protected class's static initialiser calls a runtime check, first, before any of
the class's own static initialisation runs. That check reads the class's own current bytes
off the classpath, computes a SHA-256 hash, and compares it against the expected
value recorded at protect-time, throwing a SecurityException immediately on a
mismatch, before any of the class's own code executes.
A checksum covering a class's own final bytes can't be embedded inside those same bytes without excluding its own storage location from what it covers, and carving one constant's bytes out of a serialized class file is the kind of fragile byte-offset patching this project avoids. Instead, every class's checksum is stored in a single separate bundled resource, computed only after every other bytecode mutation, decompiler-resistant wrapping, the anti-tamper call injection itself, has already happened, so the checksum always matches the exact bytes that ship.
Detects a class file edited in isolation after protection while its checksum entry is left alone, the common naive-patch pattern, for example editing a single class to defeat an embedded licence check. It does not resist an attacker who edits the checksum resource and the target class together (both are equally editable jar entries), and it does not resist an attacker who modifies a running JVM's in-memory state directly rather than the class file on disk.
SecurityException,
thrown before any of that class's own initialisation or methods can run. Every class in an
unmodified Apache Commons Exec build loads and verifies, with its checksum
populated.