pinpoint-apm/pinpoint · error · RuntimeException

${className} define fail Caused by:${causeMessage}

Error message

${className} define fail Caused by:${causeMessage}

What it means

ReflectionDefineClass.defineClass uses reflection on ClassLoader.defineClass to inject instrumented bytecode into the target JVM. When the VM rejects the class (InvocationTargetException wrapping a LinkageError/ClassFormatError) or the reflective call itself fails, handleDefineClassFail wraps the cause in a RuntimeException '<className> define fail Caused by:<causeMessage>'.

Source

Thrown at agent-module/profiler/src/main/java/com/navercorp/pinpoint/profiler/instrument/classloading/ReflectionDefineClass.java:52

        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);
        }
    }

    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

  1. Read the Caused-by chain: fix the underlying ClassFormatError/LinkageError (usually a faulty transform plugin).
  2. Disable the Pinpoint plugin/transformer producing the bad bytecode via profiling config to isolate the culprit.
  3. Check JVM/Pinpoint agent version compatibility (e.g. unsafe/reflection define restrictions on JDK 11+).
  4. Exclude the failing class from instrumentation via the profiler's exclude options.

Example fix

// before (agent config)
profiler.instrument.classloading=reflection
// after (fall back for JPMS/JDK11+)
profiler.instrument.classloading=unsafe
Defensive patterns

Strategy: try-catch

Validate before calling

// JVM-side guard before agent startup
String javaSpec = System.getProperty("java.specification.version");
if (Double.parseDouble(javaSpec) >= 11) {
  // prefer non-reflective define path / verified agent build
}

Try / catch

try {
    Class<?> c = reflectionDefineClass.defineClass(classLoader, name, bytes);
} catch (RuntimeException e) {
    logger.warn("define failed for {} : {}", name, e.getCause(), e);
    // fall back to excluding the class from instrumentation
}

Prevention

When it happens

Trigger: DEFINE_CLASS.invoke(classLoader, name, bytes, 0, bytes.length) throws: the VM rejects the transformed bytecode (ClassFormatError, LinkageError, duplicate class definition), or the reflective Method invocation fails (ReflectiveOperationException).

Common situations: A bytecode transform plugin produced invalid bytecode for that class; the class was already defined by the same loader (duplicate define); Java module system (JPMS) blocks defining into a restricted loader; Pinpoint agent version incompatible with the target JVM version.

Related errors


AI-assisted analysis of pinpoint-apm/pinpoint@744c3d3075 (2026-09-07). Data as JSON: /api/errors/03dd6a34e4c4db1d. Report an issue: GitHub.