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
- Filter directory entries before opening: only call openJarFile on entries where Files.isRegularFile(path) is true.
- If a JAR was accidentally extracted into a folder with the same name, re-deploy the actual .jar file.
- Fix the path construction so the individual JAR file (not its containing directory) is passed.
- 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 scanning directories, filter with Files.isRegularFile before opening entries.
- Never pass a lib/plugins directory itself to an API expecting a single JAR path.
- Watch for extracted folders named like the JAR after unpacking archives.
- Append the JAR file name to directory-based config values instead of passing the directory.
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
- not found
- not file
- negative cache size:${size}
- negative tick
- fromApplicationNames and fromServiceTypeCodes must have the
AI-assisted analysis of pinpoint-apm/pinpoint@744c3d3075 (2026-09-07).
Data as JSON: /api/errors/fac1c77f3c187cde.
Report an issue: GitHub.