pinpoint-apm/pinpoint · critical · IllegalStateException
Cannot access ClassLoader.defineClass(String, byte[], int, i
Error message
Cannot access ClassLoader.defineClass(String, byte[], int, int)
What it means
ReflectionDefineClass obtains a reflective handle to the protected ClassLoader.defineClass(String, byte[], int, int) method in a static initializer and calls setAccessible(true). If the JVM refuses (method missing or reflective access denied by the module system / SecurityManager), an IllegalStateException is thrown during class initialization, failing agent startup before any plugin is loaded. Pinpoint uses this to define plugin classes into arbitrary application classloaders.
Source
Thrown at agent-module/profiler/src/main/java/com/navercorp/pinpoint/profiler/instrument/classloading/ReflectionDefineClass.java:38
import org.apache.logging.log4j.Logger;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* @author Woonduk Kang(emeroad)
*/
final class ReflectionDefineClass implements DefineClass {
private final Logger logger = LogManager.getLogger(this.getClass());
private static final Method DEFINE_CLASS;
static {
try {
DEFINE_CLASS = ClassLoader.class.getDeclaredMethod("defineClass", String.class, byte[].class, int.class, int.class);
DEFINE_CLASS.setAccessible(true);
} catch (ReflectiveOperationException e) {
throw new IllegalStateException("Cannot access ClassLoader.defineClass(String, byte[], int, int)", e);
}
}
@Override
public Class<?> defineClass(ClassLoader classLoader, String name, byte[] bytes) {
if (logger.isDebugEnabled()) {
logger.debug("define class:{} cl:{}", name, classLoader);
}
try {
return (Class<?>) DEFINE_CLASS.invoke(classLoader, name, bytes, 0, bytes.length);
} catch (InvocationTargetException e) {
// unwrap: the message of the LinkageError/ClassFormatError thrown by the VM is on the cause
final Throwable cause = e.getCause() != null ? e.getCause() : e;
throw handleDefineClassFail(classLoader, name, cause);
} catch (ReflectiveOperationException e) {
throw handleDefineClassFail(classLoader, name, e);
}
}View on GitHub (pinned to 744c3d3075)
Solutions
- Add the required JVM flags: --add-opens java.base/java.lang=ALL-UNNAMED (plus any others listed in the agent startup log) to the application's launch command.
- Remove or relax the SecurityManager policy so ReflectPermission("suppressAccessChecks") is granted to the pinpoint agent codebase.
- Verify the pinpoint agent version is certified for your JDK; upgrade the agent if running on a newer JDK that changed access rules.
- If the SecurityManager is not actually required, disable it (e.g. -Djava.security.manager=allow is not enough on newer JDKs — remove the manager).
- Confirm the JVM is a standard OpenJDK/HotSpot build supported by pinpoint, not a hardened variant stripping protected members.
Example fix
// before java -jar app.jar // after java --add-opens java.base/java.lang=ALL-UNNAMED -javaagent:$AGENT_HOME/pinpoint-bootstrap.jar -jar app.jar
Defensive patterns
Strategy: validation
Validate before calling
// preflight check before enabling the pinpoint agent on a new JVM
boolean canDefine = false;
try {
Method m = ClassLoader.class.getDeclaredMethod("defineClass", String.class, byte[].class, int.class, int.class);
m.setAccessible(true);
canDefine = true;
} catch (ReflectiveOperationException e) {
System.err.println("Agent unsupported: need --add-opens java.base/java.lang=ALL-UNNAMED");
}
if (!canDefine) throw new IllegalStateException("JVM blocks ClassLoader.defineClass reflection; add --add-opens flags"); Type guard
static boolean supportsReflectiveDefineClass() {
try {
Method m = ClassLoader.class.getDeclaredMethod("defineClass", String.class, byte[].class, int.class, int.class);
m.setAccessible(true);
return true;
} catch (ReflectiveOperationException | SecurityException e) {
return false;
}
} Try / catch
try {
agentBootstrap.start();
} catch (IllegalStateException e) {
if (e.getMessage().contains("Cannot access ClassLoader.defineClass")) {
System.err.println("Restart JVM with: --add-opens java.base/java.lang=ALL-UNNAMED");
} else throw e;
} Prevention
- Include --add-opens flags in the standard JVM launch template for every environment.
- Test agent startup on the exact JDK build (including vendor/custom builds) before rollout.
- Audit SecurityManager policies; grant ReflectPermission("suppressAccessChecks") to the agent codebase or drop the SecurityManager.
- Track pinpoint agent release notes for JDK support before upgrading the runtime.
When it happens
Trigger: The agent runs on a JVM where ClassLoader.getDeclaredMethod("defineClass", ...) fails or setAccessible(true) is rejected: JDK 9+ with strong encapsulation and no --add-opens for java.lang, a SecurityManager denying ReflectPermission("suppressAccessChecks"), or an exotic/hardened JVM that hides defineClass.
Common situations: Upgrading the target app to JDK 16+ where default strong encapsulation blocks setAccessible on JDK internals; containers applying legacy SecurityManager policies; running the agent on an unsupported or custom JDK build.
Related errors
- Cannot access URLClassLoader.addURL(URL)
- pinpoint start failed.
- initialize fail Caused by:
- invoke fail Caused by:
- bootstrapClassLoader not found Caused by:
AI-assisted analysis of pinpoint-apm/pinpoint@744c3d3075 (2026-09-07).
Data as JSON: /api/errors/05d950b5ef035960.
Report an issue: GitHub.