{"record":{"id":"fac1c77f3c187cde","repo":"pinpoint-apm/pinpoint","slug":"is-directory","errorCode":null,"errorMessage":" is directory","messagePattern":" is directory","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"agent-module/bootstraps/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/agentdir/JarFileUtils.java","lineNumber":37,"sourceCode":"import java.io.IOException;\nimport java.nio.file.Files;\nimport java.nio.file.Path;\nimport java.util.Objects;\nimport java.util.jar.JarFile;\n\n/**\n * @author Woonduk Kang(emeroad)\n */\nfinal class JarFileUtils {\n\n    public static JarFile openJarFile(Path path) {\n        Objects.requireNonNull(path, \"path\");\n\n        if (!Files.exists(path)) {\n            throw new IllegalArgumentException(path + \" not found\");\n        }\n        if (Files.isDirectory(path)) {\n            throw new IllegalArgumentException(path + \" is directory\");\n        }\n        if (!Files.isRegularFile(path)) {\n            throw new IllegalArgumentException(path + \" not file\");\n        }\n        if (!Files.isReadable(path)) {\n            throw new IllegalArgumentException(path + \" can read\");\n        }\n        try {\n            return new JarFile(path.toFile());\n        } catch (IOException e) {\n            throw new IllegalStateException(path + \" create fail Caused by:\" + e.getMessage(), e);\n        }\n    }\n}\n","sourceCodeStart":19,"sourceCodeEnd":52,"githubUrl":"https://github.com/pinpoint-apm/pinpoint/blob/744c3d3075e595656abb1ae331ad2c0e4c9eb996/agent-module/bootstraps/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/agentdir/JarFileUtils.java#L19-L52","documentation":"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.","triggerScenarios":"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.","commonSituations":"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).","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."],"exampleFix":"// before\nfor (Path p : Files.list(libDir).collect(toList())) {\n    jars.add(JarFileUtils.openJarFile(p)); // dirs included\n}\n// after\ntry (Stream<Path> s = Files.list(libDir)) {\n    s.filter(Files::isRegularFile)\n     .filter(p -> p.toString().endsWith(\".jar\"))\n     .forEach(p -> jars.add(JarFileUtils.openJarFile(p)));\n}","handlingStrategy":"validation","validationCode":"Path p = candidate.toAbsolutePath();\nif (Files.isDirectory(p)) {\n    throw new IllegalArgumentException(\"Expected a JAR file, got directory: \" + p);\n}","typeGuard":null,"tryCatchPattern":"try {\n    JarFile jar = JarFileUtils.openJarFile(path);\n} catch (IllegalArgumentException e) {\n    if (String.valueOf(e.getMessage()).endsWith(\"is directory\")) {\n        logger.warn(\"Skipping directory entry: {}\", path);\n    } else {\n        throw e;\n    }\n}","preventionTips":["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."],"tags":["jar","directory","illegal-argument","validation"],"backgroundTag":"path-is-not-a-directory","analyzedSha":"744c3d3075e595656abb1ae331ad2c0e4c9eb996","analyzedAt":"2026-09-07T18:48:45.289Z","contentChangedAt":"2026-09-07T18:48:45.289Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}