pinpoint-apm/pinpoint · error · PinpointException

Failed to load plugin class ${className} with classLoader ${

Error message

Failed to load plugin class ${className} with classLoader ${classLoader}

What it means

PinpointException wrapping any failure while injecting a class into the bootstrap class loader. After appending the bootstrap jar to the search path, Class.forName(className, false, null) failed (typically ClassNotFoundException), so the handler logs a warning and rethrows a descriptive PinpointException including the class name and class loader.

Source

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

    private final Object lock = new Object();
    private volatile boolean injectedToRoot = false;

    public BootstrapClassLoaderHandler(PluginConfig pluginConfig, InstrumentEngine instrumentEngine) {
        this.pluginConfig = Objects.requireNonNull(pluginConfig, "pluginConfig");
        this.instrumentEngine = Objects.requireNonNull(instrumentEngine, "instrumentEngine");
    }

    @Override
    @SuppressWarnings("unchecked")
    public <T> Class<? extends T> injectClass(ClassLoader classLoader, String className) {
        if (classLoader != Object.class.getClassLoader()) {
            throw new IllegalStateException("not BootStrapClassLoader");
        }
        try {
            return (Class<T>) injectClass0(className);
        } catch (Exception e) {
            logger.warn("Failed to load plugin class {} with classLoader {}", className, classLoader, e);
            throw new PinpointException("Failed to load plugin class " + className + " with classLoader " + classLoader, e);
        }
    }

    private Class<?> injectClass0(String className) throws IllegalArgumentException, ClassNotFoundException {
        appendToBootstrapClassLoaderSearch();
        return Class.forName(className, false, null);
    }

    private void appendToBootstrapClassLoaderSearch() {
        // DCL
        if (injectedToRoot) {
            return;
        }
        synchronized (lock) {
            if (this.injectedToRoot == false) {
                instrumentEngine.appendToBootstrapClassPath(pluginConfig.getPluginJarFile());
                // Memory visibility WARNING
                // Reordering is not recommended.

View on GitHub (pinned to 744c3d3075)

Solutions

  1. Verify the class is packaged in the bootstrap jar that gets appended to the bootstrap class loader search
  2. Rebuild/redeploy the agent so the bootstrap jar contains the helper class
  3. Check the wrapped cause (logged warn) for the underlying reason
  4. Correct the class name if it was renamed in a recent version

Example fix

// before
<exclude>com/bootstrap/OldHelper.class</exclude>
// after
<include>com/bootstrap/Helper.class</include> <!-- packaged into bootstrap jar -->
Defensive patterns

Strategy: try-catch

Try / catch

try {
    return handler.injectClass(classLoader, className);
} catch (PinpointException e) {
    logger.error("bootstrap class {} missing from bootstrap jar; cause: {}", className, e.getCause(), e);
    throw e;
}

Prevention

When it happens

Trigger: injectClass0 fails with ClassNotFoundException because the class is not in the bootstrap jar appended via appendToBootstrapClassLoaderSearch; a helper class was not packaged into the bootstrap jar at build/deploy time.

Common situations: Rebuilt agent where a bootstrap helper class was renamed or removed; plugin declaring a bootstrap class that was never added to pinpoint's bootstrap jar; packaging scripts excluding the class.

Related errors


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