Every protected class's static initialiser also calls a runtime check that inspects the
JVM's own reported startup arguments for the standard flags a debugger attaches through
(-agentlib:jdwp, -Xrunjdwp), cached once per JVM process, and
throws a SecurityException if found.
This check does not treat a general -javaagent
as a signal. Production JVMs commonly run legitimate application-performance-monitoring or
observability agents, and treating that as "under attack" would be a damaging false
positive against your own production deployment. JDWP carries no equivalent risk: nobody
ships a production JVM with remote debugging enabled by accident, so this line is drawn
to keep the false-positive rate near zero, even though it detects less.
Detects the standard way a debugger attaches to a JVM at startup. It does not resist an
attacker who attaches through some other channel this check doesn't inspect, and it does not
resist an attacker who reads this check's own logic, undisguised in what remains of the
bytecode, or easy to find once dev.rjni.runtime classes are identified, and
patches it out. It is also a known false-positive risk against a legitimate
user who launches your protected jar with remote debugging enabled for their
own troubleshooting: it fails with a clear error in that case.