{"record":{"id":"b970f0acceb61106","repo":"Tencent/matrix","slug":"obj-obj-is-not-closeable","errorCode":null,"errorMessage":"obj ${obj} is not closeable","messagePattern":"obj (.+?) is not closeable","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"matrix/matrix-android/matrix-commons/src/main/java/com/tencent/matrix/javalib/util/IOUtil.java","lineNumber":143,"sourceCode":"            try {\n                ((Closeable) obj).close();\n            } catch (Throwable ignored) {\n                // ignore\n            }\n        } else if (obj instanceof AutoCloseable) {\n            try {\n                ((AutoCloseable) obj).close();\n            } catch (Throwable ignored) {\n                // ignore\n            }\n        } else if (obj instanceof ZipFile) {\n            try {\n                ((ZipFile) obj).close();\n            } catch (Throwable ignored) {\n                // ignore\n            }\n        } else {\n            throw new IllegalArgumentException(\"obj \" + obj + \" is not closeable\");\n        }\n    }\n\n    private IOUtil() {\n        throw new UnsupportedOperationException();\n    }\n}\n","sourceCodeStart":125,"sourceCodeEnd":151,"githubUrl":"https://github.com/Tencent/matrix/blob/3b8293bd65d47eeea7caf1f32a3a5d4d5eab60e7/matrix/matrix-android/matrix-commons/src/main/java/com/tencent/matrix/javalib/util/IOUtil.java#L125-L151","documentation":"IOUtil.closeQuietly closes Closeable, ZipFile, and similar known closeable types while swallowing exceptions; if the object is none of the recognized types it throws IllegalArgumentException 'obj X is not closeable'. It's a programming-error guard: you passed something the utility doesn't know how to close.","triggerScenarios":"Passing an object that is neither Closeable nor ZipFile (e.g. a raw Channel type on an old API level, a custom resource, or null wrapper types) to IOUtil.closeQuietly.","commonSituations":"Refactoring a stream to a new resource class that doesn't implement Closeable; calling closeQuietly with AutoCloseable implementations that predate Closeable; misuse in tests with mocks that don't implement the interface.","solutions":["Make the resource implement java.io.Closeable (or AutoCloseable and handle it) before passing to closeQuietly.","Close it directly with try-with-resources instead of IOUtil.","Add an instanceof branch in a local helper for the specific type (e.g. Channel) that IOUtil doesn't cover.","Check for null first — a wrong variable being passed is the usual root cause."],"exampleFix":"// before\nIOUtil.closeQuietly(someChannel); // IllegalArgumentException\n// after\nif (someChannel instanceof Closeable) {\n    IOUtil.closeQuietly(someChannel);\n} else if (someChannel != null) {\n    try { someChannel.close(); } catch (Throwable ignored) { }\n}","handlingStrategy":"type-guard","validationCode":"if (obj instanceof Closeable || obj instanceof ZipFile) {\n    IOUtil.closeQuietly(obj);\n}","typeGuard":"static boolean isCloseable(Object obj) {\n    return obj instanceof Closeable || obj instanceof ZipFile;\n}","tryCatchPattern":"try {\n    IOUtil.closeQuietly(resource);\n} catch (IllegalArgumentException e) {\n    Log.w(TAG, \"resource not closeable by IOUtil: \" + resource.getClass());\n}","preventionTips":["Ensure resources implement java.io.Closeable before handing them to IOUtil.","Prefer try-with-resources for anything AutoCloseable that IOUtil doesn't recognize.","Check the variable you pass — wrong-variable bugs surface here.","Extend with a local helper for special types (e.g. Channels) instead of forcing IOUtil."],"tags":["java","io","resource-cleanup","argument-validation"],"backgroundTag":"invalid-argument-value","analyzedSha":"3b8293bd65d47eeea7caf1f32a3a5d4d5eab60e7","analyzedAt":"2026-09-08T08:01:39.722Z","contentChangedAt":"2026-09-08T08:01:39.722Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}