pinpoint-apm/pinpoint · error · PinpointException

Failed to load plugin class {} with classLoader {}

Error message

Failed to load plugin class {} with classLoader {}

What it means

PlainClassLoaderHandler.injectClass loads plugin classes through the target application classloader. Any exception while checking the plugin package filter or defining the class is logged, wrapped in a PinpointException, and rethrown. It indicates the plugin class could not be defined or resolved in the application classloader.

Source

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

        this.defineClass = Objects.requireNonNull(defineClass, "defineClass");
        this.pluginConfig = Objects.requireNonNull(pluginConfig, "pluginConfig");
        this.pluginJarReader = new JarReader(pluginConfig.getPluginJarFile());
    }

    @Override
    @SuppressWarnings("unchecked")
    public <T> Class<? extends T> injectClass(ClassLoader classLoader, String className) {
        if (classLoader == Object.class.getClassLoader()) {
            throw new IllegalStateException("BootStrapClassLoader");
        }

        try {
            if (!isPluginPackage(className, classLoader)) {
                return loadClass(classLoader, className);
            }
            return (Class<T>) injectClass0(classLoader, 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);
        }
    }

    @Override
    public InputStream getResourceAsStream(ClassLoader targetClassLoader, String internalName) {
        try {
            final String name = JavaAssistUtils.jvmNameToJavaName(internalName);
            if (!isPluginPackage(name, targetClassLoader)) {
                return targetClassLoader.getResourceAsStream(internalName);
            }

            getClassLoaderAttachment(targetClassLoader, internalName);
            final InputStream inputStream = getPluginInputStream(internalName);
            if (inputStream != null) {
                return inputStream;
            }

View on GitHub (pinned to 744c3d3075)

Solutions

  1. Unwrap the PinpointException cause to see the real error (ClassNotFound/Linkage/IO).
  2. Ensure the plugin jar is on the plugin directory and its package passes the plugin package filter.
  3. Check for duplicate plugin jars defining the same class causing LinkageError.
  4. Verify the class's dependencies exist in the target application classloader.

Example fix

// before
Class<?> c = injector.injectClass(classLoader, "com.example.PluginAdvice");
// after
try {
    Class<?> c = injector.injectClass(classLoader, "com.example.PluginAdvice");
} catch (PinpointException e) {
    logger.error("plugin class load failed: {}", e.getCause(), e);
    throw e;
}
Defensive patterns

Strategy: try-catch

Validate before calling

if (!pluginConfig.getPluginPackageFilter().accept(className, classLoader)) { throw new IllegalArgumentException("not a plugin package: " + className); }

Try / catch

try { return injector.injectClass(classLoader, className); } catch (PinpointException e) { log.error("plugin class {} failed: {}", className, e.getCause(), e); throw e; }

Prevention

When it happens

Trigger: injectClass called for a class in a plugin package where injectClass0 (define0/class loading) throws — missing plugin resource, linkage errors, or a failure in isPluginPackage/loadClass path.

Common situations: Plugin class referencing classes unavailable in the app classloader; duplicate class definition (LinkageError); plugin jar corrupted; class name mismatch with packaged resource; classloader isolation (containers) preventing visibility.

Related errors


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