pinpoint-apm/pinpoint · error · IOException

system classloader is null.

Error message

system classloader is null.

What it means

IOException thrown by ClassReaderWrapper when it needs a fallback classloader to read a class resource and ClassLoader.getSystemClassLoader() returns null. Pinpoint reads the class's bytecode via getResourceAsStream; without any usable classloader it cannot proceed.

Source

Thrown at agent-module/profiler/src/main/java/com/navercorp/pinpoint/profiler/instrument/classreading/ClassReaderWrapper.java:81

        if (readAttributes) {
            readAttributes();
        }
    }

    public ClassReaderWrapper(final ClassLoader classLoader, final String classInternalName) throws IOException {
        this(classLoader, classInternalName, false);
    }

    // classloader and class internal name.
    public ClassReaderWrapper(final ClassLoader classLoader, final String classInternalName, final boolean readAttributes) throws IOException {
        Objects.requireNonNull(classInternalName, "classInternalName");

        ClassLoader cl = classLoader;
        if (cl == null) {
            cl = ClassLoader.getSystemClassLoader();
            if (cl == null) {
                // system fail.
                throw new IOException("system classloader is null.");
            }
        }

        final String classPath = classInternalName.concat(".class");
        final InputStream in = cl.getResourceAsStream(classPath);
        if (in == null) {
            throw new IOException("not found class. classLoader=" + cl + ", classInternalName=" + classInternalName);
        }

        byte[] bytes = IOUtils.toByteArray(in);
        this.classReader = new ClassReader(bytes);
        if (readAttributes) {
            readAttributes();
        }
    }

    // class's access flags.
    public int getAccess() {

View on GitHub (pinned to 744c3d3075)

Solutions

  1. Pass an explicit non-null target ClassLoader to ClassReaderWrapper instead of relying on the null fallback.
  2. Check JVM launch options that can suppress the system classloader for the instrumented code path.
  3. If instrumenting bootstrap classes, use a classloader that can see the class (e.g. the one that triggered the transform).

Example fix

// before
new ClassReaderWrapper().readClassInternalName(internalName, null);
// after
new ClassReaderWrapper().readClassInternalName(internalName, Thread.currentThread().getContextClassLoader());
Defensive patterns

Strategy: validation

Validate before calling

ClassLoader cl = classLoader != null ? classLoader : ClassLoader.getSystemClassLoader();
if (cl == null) throw new IllegalStateException("no usable classloader available to read " + classInternalName);

Try / catch

try { wrapper.readClassInternalName(name, cl); } catch (IOException e) { if (e.getMessage().contains("system classloader is null")) { /* supply explicit loader or skip */ } throw e; }

Prevention

When it happens

Trigger: readClasspathClass/classReader initialization invoked with classLoader == null while running in an environment where the system classloader is unavailable (e.g. code running on the bootstrap classloader, some embedding/agent scenarios).

Common situations: Instrumentation of bootstrap classes where the target classloader is null and the JVM was started with -Xbootclasspath/a semantics making getSystemClassLoader() return null, or very unusual embedding setups that set the context loader to null.

Related errors


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