chinabugotech/hutool · error · IORuntimeException
Can not read file path of [{}]
Error message
Can not read file path of [{}] What it means
When listFileNames resolves a path containing the JAR path extension marker (e.g. "/path/to/x.jar!/com/foo"), it opens it as a JarFile and lists the inner entries. If opening or reading the JAR throws IOException, it is wrapped and rethrown as IORuntimeException("Can not read file path of [{}]").
Source
Thrown at hutool-core/src/main/java/cn/hutool/core/io/FileUtil.java:265
final List<String> paths = new ArrayList<>();
final File[] files = ls(path);
for (File file : files) {
if (file.isFile()) {
paths.add(file.getName());
}
}
return paths;
}
// jar文件中的路径
index = index + FileUtil.JAR_FILE_EXT.length();
JarFile jarFile = null;
try {
jarFile = new JarFile(path.substring(0, index));
// 防止出现jar!/cn/hutool/这类路径导致文件找不到
return ZipUtil.listFileNames(jarFile, StrUtil.removePrefix(path.substring(index + 1), "/"));
} catch (IOException e) {
throw new IORuntimeException(StrUtil.format("Can not read file path of [{}]", path), e);
} finally {
IoUtil.close(jarFile);
}
}
/**
* 创建File对象,相当于调用new File(),不做任何处理
*
* @param path 文件路径,相对路径表示相对项目路径
* @return File
* @since 4.1.4
*/
public static File newFile(String path) {
return new File(path);
}
/**
* 创建File对象,自动识别相对或绝对路径,相对路径将自动从ClassPath下寻找View on GitHub (pinned to 8870454b2a)
Solutions
- Verify the JAR portion of the path exists and is a readable file before listing.
- Confirm the path genuinely uses the ".jar!/entry" convention and is not a false match.
- Catch IORuntimeException, inspect getCause() for the underlying IOException, and report the specific JAR path.
Example fix
// before
List<String> names = FileUtil.listFileNames("/app/lib/bad.jar!/cn/hutool");
// after: confirm the jar exists first
String jarPart = "/app/lib/bad.jar";
if (FileUtil.isFile(jarPart)) {
List<String> names = FileUtil.listFileNames(jarPart + "!/cn/hutool");
} Defensive patterns
Strategy: try-catch
Validate before calling
String jarPart = path.substring(0, path.lastIndexOf(".jar!") + 4);
if (!FileUtil.isFile(jarPart)) {
// JAR missing/unreadable: do not attempt to list
} Type guard
static boolean isReadableJarPath(String path) {
int i = path.lastIndexOf(".jar!");
if (i < 0) return false;
File jar = new File(path.substring(0, i + 4));
return jar.isFile() && jar.canRead();
} Try / catch
try {
return FileUtil.listFileNames(jarPath);
} catch (IORuntimeException e) {
Throwable cause = e.getCause(); // underlying IOException
// report which JAR could not be read; treat as missing resource
} Prevention
- Confirm the JAR portion of a ".jar!/entry" path exists and is readable before listing.
- Watch for paths that merely contain ".jar!" but are not real JARs.
- Inspect getCause() for the real IOException when diagnosing.
When it happens
Trigger: Calling a file-name listing method on a path with a ".jar!" marker where the JAR is missing, corrupt, truncated, locked, or the inner entry path is malformed.
Common situations: Corrupt or partially-downloaded JAR; JAR deleted between path resolution and read; a path that coincidentally contains ".jar!" but is not a real JAR; permission/lock preventing the JarFile constructor from opening it.
Related errors
- Destination Dir must be a Directory !
- Not a regular file!
- Path [{}] is not directory!
- File path is blank!
- File uri is null!
AI-assisted analysis of chinabugotech/hutool@8870454b2a (2026-08-14).
Data as JSON: /api/errors/75c1f89c5f165add.
Report an issue: GitHub.