pinpoint-apm/pinpoint · error · IllegalArgumentException

is directory

Error message

 is directory

What it means

JarFileUtils.openJarFile(Path) rejects paths that refer to a directory: if Files.isDirectory(path) is true it throws IllegalArgumentException with "<path> is directory". JAR files must be regular files, so passing a directory is treated as a caller bug and fails fast before attempting to open it.

Source

Thrown at agent-module/bootstraps/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/agentdir/JarFileUtils.java:37

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Objects;
import java.util.jar.JarFile;

/**
 * @author Woonduk Kang(emeroad)
 */
final class JarFileUtils {

    public static JarFile openJarFile(Path path) {
        Objects.requireNonNull(path, "path");

        if (!Files.exists(path)) {
            throw new IllegalArgumentException(path + " not found");
        }
        if (Files.isDirectory(path)) {
            throw new IllegalArgumentException(path + " is directory");
        }
        if (!Files.isRegularFile(path)) {
            throw new IllegalArgumentException(path + " not file");
        }
        if (!Files.isReadable(path)) {
            throw new IllegalArgumentException(path + " can read");
        }
        try {
            return new JarFile(path.toFile());
        } catch (IOException e) {
            throw new IllegalStateException(path + " create fail Caused by:" + e.getMessage(), e);
        }
    }
}

View on GitHub (pinned to 744c3d3075)

Solutions

  1. Filter directory entries before opening: only call openJarFile on entries where Files.isRegularFile(path) is true.
  2. If a JAR was accidentally extracted into a folder with the same name, re-deploy the actual .jar file.
  3. Fix the path construction so the individual JAR file (not its containing directory) is passed.
  4. Fix the config value that specifies a single JAR path so it points to a file, not a directory.

Example fix

// before
for (Path p : Files.list(libDir).collect(toList())) {
    jars.add(JarFileUtils.openJarFile(p)); // dirs included
}
// after
try (Stream<Path> s = Files.list(libDir)) {
    s.filter(Files::isRegularFile)
     .filter(p -> p.toString().endsWith(".jar"))
     .forEach(p -> jars.add(JarFileUtils.openJarFile(p)));
}
Defensive patterns

Strategy: validation

Validate before calling

Path p = candidate.toAbsolutePath();
if (Files.isDirectory(p)) {
    throw new IllegalArgumentException("Expected a JAR file, got directory: " + p);
}

Try / catch

try {
    JarFile jar = JarFileUtils.openJarFile(path);
} catch (IllegalArgumentException e) {
    if (String.valueOf(e.getMessage()).endsWith("is directory")) {
        logger.warn("Skipping directory entry: {}", path);
    } else {
        throw e;
    }
}

Prevention

When it happens

Trigger: Calling JarFileUtils.openJarFile(path) where path points at a directory — typically when a glob/scandir collects paths loosely (e.g. passing the lib directory itself, or a path whose JAR segment was lost) instead of an individual .jar file.

Common situations: Directory-scanning code that passes every entry (including subdirectories) to openJarFile; configuration where a directory path is given where a file path is expected; a '.jar' named directory created by mistake (unzipped in place leaving a folder named like the JAR).

Related errors


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