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

PluginClassInjector.injectClass() is the single entry point that loads plugin classes into application classloaders, dispatching to bootstrap/URLClassLoader/plain handlers. Any Throwable escaping those handlers (IOException reading the jar, 'interface not found' PinpointException, LinkageError, etc.) is caught and rethrown as a PinpointException wrapping the original cause. The message only names the class and classloader — the actionable information is in the cause chain.

Source

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

    @Override
    public <T> Class<? extends T> injectClass(ClassLoader classLoader, String className) {
        try {
            if (bootstrapCore.isBootstrapPackage(className)) {
                return bootstrapCore.loadClass(className);
            }

            if (bootstrapClassLoader == classLoader) {
                return bootstrapClassLoaderHandler.injectClass(null, className);
            } else if (classLoader instanceof URLClassLoader) {
                return urlClassLoaderHandler.injectClass(classLoader, className);
            } else {
                return plainClassLoaderHandler.injectClass(classLoader, className);
            }
        } catch (Throwable e) {
            // fixed for LinkageError
            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);
        }
    }

    @Override
    public InputStream getResourceAsStream(ClassLoader targetClassLoader, String internalName) {
        try {
            if (bootstrapCore.isBootstrapPackageByInternalName(internalName)) {
                return bootstrapCore.openStream(internalName);
            }
            if (targetClassLoader == null) {
                return bootstrapClassLoaderHandler.getResourceAsStream(null, internalName);
            } else if (targetClassLoader instanceof URLClassLoader) {
                final URLClassLoader urlClassLoader = (URLClassLoader) targetClassLoader;
                return urlClassLoaderHandler.getResourceAsStream(urlClassLoader, internalName);
            } else {
                return plainClassLoaderHandler.getResourceAsStream(targetClassLoader, internalName);
            }
        } catch (Throwable e) {

View on GitHub (pinned to 744c3d3075)

Solutions

  1. Read the full logged stack trace ('Failed to load plugin class ...') and fix the root cause it names (jar read fail, interface not found, reflective access, etc.).
  2. Verify the plugin jar is complete and readable: `unzip -t`, correct permissions, and matching plugin/agent versions.
  3. Confirm the target JVM supports the plugin classes' class-file version (plugin built with a newer JDK than the app's JVM — rebuild plugin with --release matching the runtime).
  4. Check the plugin dir for duplicate or overlapping plugin jars; remove older versions.
  5. If reflective access is the cause, upgrade the pinpoint agent to a version compatible with your JDK or add the required --add-opens/--add-exports JVM flags.
  6. Test the plugin outside pinpoint (plain loadClass) to confirm the jar is self-consistent.

Example fix

// caller side: always inspect the cause, the message is only a wrapper
try {
    injector.injectClass(appClassLoader, "com.example.PluginTransformer");
} catch (PinpointException e) {
    logger.error("plugin injection failed; root cause:", e.getCause());
    // fix root cause (jar integrity / JDK flags / version alignment) before retrying
}
Defensive patterns

Strategy: try-catch

Try / catch

try {
    Class<?> c = injector.injectClass(targetClassLoader, pluginClassName);
} catch (PinpointException e) {
    // this message is only a wrapper; the actionable info is the cause
    Throwable root = e;
    while (root.getCause() != null) root = root.getCause();
    logger.error("plugin injection of {} failed, root cause {}: {}",
            pluginClassName, root.getClass().getName(), root.getMessage());
    // dispatch on root cause: IOException -> jar integrity; 'not found' -> packaging; LinkageError -> duplicates/JDK
}

Prevention

When it happens

Trigger: Any failure inside urlClassLoaderHandler.injectClass() (addURL reflection failure, 'invalid ClassLoader') or plainClassLoaderHandler.injectClass() (jar read IOException from readJar(), missing-interface PinpointException, ClassNotFoundException wrapped as RuntimeException, LinkageError/duplicate class definition) while injecting a plugin class into the target application classloader.

Common situations: Corrupted or unreadable plugin jars; incomplete plugin jars missing dependency interfaces; running the agent on a JDK where reflective defineClass/addURL is blocked (module system restrictions); plugin classes compiled for a higher class-file version than the target JVM; two plugins defining the same class into one classloader.

Related errors


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