pinpoint-apm/pinpoint · error · RuntimeException
${className} define fail Caused by:${causeMessage}
Error message
${className} define fail Caused by:${causeMessage} What it means
UnsafeDefineClass.defineClass uses sun.misc.Unsafe.defineClass to inject bytecode. As in ReflectionDefineClass, when the VM rejects the class or the Unsafe invocation fails, handleDefineClassFail throws RuntimeException '<className> define fail Caused by:<causeMessage>'.
Source
Thrown at agent-module/profiler/src/main/java/com/navercorp/pinpoint/profiler/instrument/classloading/UnsafeDefineClass.java:62
UNSAFE = theUnsafe.get(null);
DEFINE_CLASS = unsafeClass.getMethod("defineClass",
String.class, byte[].class, int.class, int.class, ClassLoader.class, ProtectionDomain.class);
} catch (ReflectiveOperationException e) {
throw new IllegalStateException("Cannot access sun.misc.Unsafe.defineClass", 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(UNSAFE, name, bytes, 0, bytes.length, classLoader, null);
} 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);
}
}
private RuntimeException handleDefineClassFail(ClassLoader classLoader, String className, Throwable cause) {
logger.warn("{} define fail cl:{} Caused by:{}", className, classLoader, cause.getMessage(), cause);
return new RuntimeException(className + " define fail Caused by:" + cause.getMessage(), cause);
}
}
View on GitHub (pinned to 744c3d3075)
Solutions
- Read the cause message for the VM-level reason and fix the offending transformer.
- Switch instrument classloading mode in Pinpoint config (e.g. to reflection/ASMFallback) if Unsafe is unavailable.
- Exclude the failing class from instrumentation.
- Upgrade the agent to a build supporting the running JDK.
Example fix
// before
return (Class<?>) DEFINE_CLASS.invoke(UNSAFE, name, bytes, 0, bytes.length, classLoader, null);
// after (guard availability)
if (!UNSAFE_SUPPORTED) {
return reflectionDefineClass.defineClass(classLoader, name, bytes);
} Defensive patterns
Strategy: fallback
Validate before calling
// check Unsafe availability at agent init
boolean unsafeOk;
try {
Class<?> u = Class.forName("sun.misc.Unsafe");
unsafeOk = u.getDeclaredMethod("defineClass", String.class, byte[].class, int.class, int.class, ClassLoader.class, java.security.ProtectionDomain.class) != null;
} catch (ReflectiveOperationException e) {
unsafeOk = false;
} Try / catch
try {
return unsafeDefineClass.defineClass(classLoader, name, bytes);
} catch (RuntimeException e) {
logger.warn("Unsafe define failed for {} ({}), falling back", name, e.getCause());
return reflectionDefineClass.defineClass(classLoader, name, bytes);
} Prevention
- Detect sun.misc.Unsafe.defineClass availability at startup and select the define strategy then.
- On JDK 9+ set --add-opens if reflective access is required.
- Keep bytecode-transformed classes small and verified.
When it happens
Trigger: DEFINE_CLASS.invoke(UNSAFE, name, bytes, 0, bytes.length, classLoader, null) throws InvocationTargetException (VM rejected the class: ClassFormatError/LinkageError/duplicate define) or ReflectiveOperationException (Unsafe API missing/changed).
Common situations: Invalid transformed bytecode from a plugin; class already defined by the target loader; newer JDKs restricting/removing sun.misc.Unsafe.defineClass (JDK 11+ deprecation, removal paths); agent-JVM version mismatch.
Related errors
- source and advice class node must not be null.
- ${className} define fail Caused by:${causeMessage}
- ${name} define fail Caused by:${e.getMessage()}
- Unknown InstrumentEngine:${instrumentEngine}
- @Aspect not found. adviceClass=${adviceClassInternalName}
AI-assisted analysis of pinpoint-apm/pinpoint@744c3d3075 (2026-09-07).
Data as JSON: /api/errors/cc52b8420e26b5ad.
Report an issue: GitHub.