{"record":{"id":"19436b4fb62fb789","repo":"Tencent/tinker","slug":"obj-cannot-be-closed","errorCode":null,"errorMessage":"obj: {} cannot be closed.","messagePattern":"obj: (.+?) cannot be closed\\.","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"tinker-android/tinker-android-loader-no-op/src/main/java/com/tencent/tinker/loader/shareutil/SharePatchFileUtil.java","lineNumber":162,"sourceCode":"            try {\n                ((Closeable) obj).close();\n            } catch (Throwable ignored) {\n                // Ignored.\n            }\n        } else if (Build.VERSION.SDK_INT >= 19 && obj instanceof AutoCloseable) {\n            try {\n                ((AutoCloseable) obj).close();\n            } catch (Throwable ignored) {\n                // Ignored.\n            }\n        } else if (obj instanceof ZipFile) {\n            try {\n                ((ZipFile) obj).close();\n            } catch (Throwable ignored) {\n                // Ignored.\n            }\n        } else {\n            throw new IllegalArgumentException(\"obj: \" + obj + \" cannot be closed.\");\n        }\n    }\n\n    public static final boolean isLegalFile(File file) {\n        return file != null && file.exists() && file.canRead() && file.isFile() && file.length() > 0;\n    }\n\n    /**\n     * For some special device whose dex2oat procedure is optimized for tinker. (e.g. vivo, oppo)\n     *\n     * Because these devices by-pass our dex2oat request, which cause vm to load tinker's dex with interpret-mode\n     * and generate nothing instead of a valid oat file. It's fine to skip the check so far.\n     *\n     * @param file\n     * @return\n     */\n    public static final boolean shouldAcceptEvenIfIllegal(File file) {\n        final boolean isSpecialManufacturer =","sourceCodeStart":144,"sourceCodeEnd":180,"githubUrl":"https://github.com/Tencent/tinker/blob/1b7ea02c239840f563ea64fb5bd286eb98d4011e/tinker-android/tinker-android-loader-no-op/src/main/java/com/tencent/tinker/loader/shareutil/SharePatchFileUtil.java#L144-L180","documentation":"SharePatchFileUtil.closeQuietly only closes objects that are AutoCloseable or ZipFile; any other object triggers IllegalArgumentException('obj: X cannot be closed.'). This is a developer-programming guard: the utility refuses to pretend it closed something it has no idea how to close.","triggerScenarios":"Calling closeQuietly(obj) with an object that implements neither AutoCloseable nor ZipFile — e.g. a legacy class exposing only a custom close()/release()/destroy() method, a plain wrapper, or a null-ish sentinel passed by mistake.","commonSituations":"Copy-pasting the closeQuietly call around streams from older APIs that pre-date AutoCloseable (some dalvik-era or vendor classes); passing a domain object instead of the resource it owns.","solutions":["Pass the actual resource object (InputStream/OutputStream/RandomAccessFile/ZipFile — all AutoCloseable), not a wrapper or owner.","If the class only has a bespoke close(), call it directly in your own try/finally instead of closeQuietly.","Wrap the non-AutoCloseable resource in a small adapter implementing AutoCloseable that delegates to its close method."],"exampleFix":"// before\nSharePatchFileUtil.closeQuietly(someLegacyHandle); // IllegalArgumentException\n\n// after\ntry {\n    someLegacyHandle.disconnect(); // its real release method\n} catch (Throwable ignored) { }","handlingStrategy":"validation","validationCode":"if (!(obj instanceof AutoCloseable) && !(obj instanceof ZipFile)) {\n    throw new IllegalArgumentException(\"Not closeable: \" + obj);\n}\nSharePatchFileUtil.closeQuietly(obj);","typeGuard":"static boolean isCloseable(Object o) { return o instanceof AutoCloseable || o instanceof java.util.zip.ZipFile; }","tryCatchPattern":null,"preventionTips":["Only pass resources implementing AutoCloseable (or ZipFile) to closeQuietly.","For legacy resources with bespoke close methods, call them in your own finally block.","Fail fast in debug builds on non-closeable objects."],"tags":["resource-management","api-misuse","java"],"backgroundTag":null,"analyzedSha":"1b7ea02c239840f563ea64fb5bd286eb98d4011e","analyzedAt":"2026-08-14T15:16:52.110Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}