MuntashirAkon/AppManager · error · FileNotFoundException
Class definition for + node.getFullPath() + is not found.
Error message
Class definition for + node.getFullPath() + is not found.
What it means
ZipFileSystem.getInputStream(node) casts node.getObject() to ZipEntry. If the node holds no cached ZipEntry (null), it throws FileNotFoundException("Class definition for <path> is not found."). The message is misleading — it actually means the zip entry object for that node was never populated or was dropped from cache.
Solutions
- Refresh/re-scan the ZipFileSystem so nodes get their ZipEntry objects attached before reading.
- Obtain the node from the live ZipFileSystem instance rather than a stale snapshot.
- Verify node.getObject() instanceof ZipEntry before calling getInputStream.
- Catch FileNotFoundException and reopen the archive to rebuild the entry index.
Example fix
// before
InputStream in = zipFs.getInputStream(staleNode);
// after
zipFs.refresh();
Node<?> node = zipFs.getNode(staleNode.getFullPath());
if (node != null && node.getObject() instanceof ZipEntry) {
InputStream in = zipFs.getInputStream(node);
} Defensive patterns
Strategy: try-catch
Validate before calling
if (!(node.getObject() instanceof ZipEntry)) { zipFs.refresh(); node = zipFs.getNode(node.getFullPath()); } Type guard
boolean hasZipEntry(Node<?> n) { return n.getObject() instanceof ZipEntry; } Try / catch
try { return zipFs.getInputStream(node); } catch (FileNotFoundException e) { zipFs.refresh(); return zipFs.getInputStream(zipFs.getNode(node.getFullPath())); } Prevention
- Re-scan the ZipFileSystem after modifications
- Use nodes from the live filesystem, not cached snapshots
- Assert getObject() instanceof ZipEntry in debug builds
When it happens
Trigger: Reading a stream for a ZIP node whose getObject() is null — typically when cacheFile() is called for a node that was not previously scanned into the zip entry index, or the entry list was rebuilt and the node's ZipEntry reference was lost.
Common situations: Extracting a file from a ZIP whose entry table was re-scanned; using a Node from a stale filesystem snapshot after the archive was modified; subclasses whose scan didn't attach ZipEntry objects to nodes; large archives where entry objects are lazily loaded.
Understand the failure class
Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.
Related errors
AI-assisted analysis of MuntashirAkon/AppManager@0152f468fc (2026-09-12).
Data as JSON: /api/errors/1982a51173e5126b.
Report an issue: GitHub.
Appendix: source
Thrown at app/src/main/java/io/github/muntashirakon/io/fs/ZipFileSystem.java:342
if (access == OsConstants.R_OK) {
return true;
}
if (access == OsConstants.W_OK) {
return Objects.requireNonNull(getOptions()).readWrite;
}
if (access == (OsConstants.R_OK | OsConstants.W_OK)) {
return Objects.requireNonNull(getOptions()).readWrite;
}
// X_OK, R_OK|X_OK, R_OK|W_OK|X_OK are false
return false;
}
@NonNull
@Override
protected InputStream getInputStream(@NonNull Node<?> node) throws IOException {
ZipEntry zipEntry = (ZipEntry) node.getObject();
if (zipEntry == null) {
throw new FileNotFoundException("Class definition for " + node.getFullPath() + " is not found.");
}
return Objects.requireNonNull(mZipFile).getInputStream(zipEntry);
}
@Override
protected void cacheFile(@NonNull Node<?> src, @NonNull File sink) throws IOException {
try (InputStream is = getInputStream(src);
FileOutputStream os = new FileOutputStream(sink)) {
IoUtils.copy(is, os);
}
}
@NonNull
private static Node<ZipEntry> buildTree(@NonNull ZipFile zipFile) {
Node<ZipEntry> rootNode = new Node<>(null, File.separator);
Enumeration<? extends ZipEntry> zipEntries = zipFile.entries();
while (zipEntries.hasMoreElements()) {
ZipEntry zipEntry = zipEntries.nextElement();View on GitHub (pinned to 0152f468fc)