{"record":{"id":"80e59679e202d5b5","repo":"MuntashirAkon/AppManager","slug":"closedchannelexception","errorCode":null,"errorMessage":"ClosedChannelException","messagePattern":"ClosedChannelException","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"libcore/io/src/main/java/io/github/muntashirakon/io/OpenFile.java","lineNumber":51,"sourceCode":"    private ByteBuffer buf;\n    private StructStat st;\n\n    private ByteBuffer getBuf() {\n        if (buf == null)\n            buf = ByteBuffer.allocateDirect(FileSystemService.PIPE_CAPACITY);\n        buf.clear();\n        return buf;\n    }\n\n    private StructStat getStat() throws ErrnoException {\n        if (st == null)\n            st = Os.fstat(fd);\n        return st;\n    }\n\n    private void ensureOpen() throws ClosedChannelException {\n        if (fd == null)\n            throw new ClosedChannelException();\n    }\n\n    @Override\n    synchronized public void close() {\n        if (fd != null) {\n            try {\n                Os.close(fd);\n            } catch (ErrnoException ignored) {\n            }\n            fd = null;\n        }\n        if (read != null) {\n            try {\n                Os.close(read);\n            } catch (ErrnoException ignored) {\n            }\n            read = null;\n        }","sourceCodeStart":33,"sourceCodeEnd":69,"githubUrl":"https://github.com/MuntashirAkon/AppManager/blob/0152f468fc9463ee02dc2ca83f6fe4989a2c4ca5/libcore/io/src/main/java/io/github/muntashirakon/io/OpenFile.java#L33-L69","documentation":"OpenFile wraps a native file descriptor with synchronized operations (lseek, size, ftruncate, sync, etc.). Internal ensureOpen() checks that fd is still non-null; once close() has been called, fd is nulled and any subsequent operation throws ClosedChannelException, mirroring java.nio channels closed-state semantics.","triggerScenarios":"Calling lseek(), size(), ftruncate(), sync() (or anything else routed through ensureOpen) after close() on the same OpenFile; concurrent close from another thread while an operation is in flight; using an OpenFile returned from a remote manager whose file was closed remotely.","commonSituations":"try-with-resources or explicit close followed by lingering references still used; races between a close in a cleanup path and a read/write worker; reopening expectations after process restart without reacquiring the OpenFile.","solutions":["Catch ClosedChannelException and reopen the file via FileSystemManager before retrying the operation","Guard usage so no operation occurs after close (lifecycle management, single owner thread)","Synchronize usage with close (the methods are synchronized; ensure the same monitor/lifecycle governs both)"],"exampleFix":"// before\nopenFile.close();\nopenFile.size(); // ClosedChannelException\n// after\nopenFile.close();\nif (!openFileClosed) { // or reopen instead\n    OpenFile reopened = fm.openFile(path, \"r\");\n    long sz = reopened.size();\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try { long sz = openFile.size(); } catch (ClosedChannelException e) { openFile = fm.openFile(path, mode); sz = openFile.size(); }","preventionTips":["Treat OpenFile as single-owner: close once, never use afterwards","Use the file's own streams and close them before closing the file","Avoid sharing OpenFile across threads without clear close ownership"],"tags":["io","closed-channel","lifecycle","fd"],"backgroundTag":"invalid-state-transition","analyzedSha":"0152f468fc9463ee02dc2ca83f6fe4989a2c4ca5","analyzedAt":"2026-09-12T14:03:37.243Z","contentChangedAt":"2026-09-12T14:03:37.243Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}