{"record":{"id":"1733b44e63145393","repo":"pxb1988/dex2jar","slug":"can-not-find-classes-dex-in-zip-file-1733b4","errorCode":null,"errorMessage":"Can not find classes.dex in zip file","messagePattern":"Can not find classes\\.dex in zip file","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"dex-reader/src/main/java/com/googlecode/d2j/reader/zip/ZipUtil.java","lineNumber":85,"sourceCode":"     * in the zip stream.\n     * \n     * @param data\n     * @return the content of classes.dex\n     * @throws IOException\n     */\n    public static byte[] readDex(byte[] data) throws IOException {\n        if (data.length < 3) {\n            throw new IOException(\"File too small to be a dex/zip\");\n        }\n        if (\"dex\".equals(new String(data, 0, 3, StandardCharsets.ISO_8859_1))) {// dex\n            return data;\n        } else if (\"PK\".equals(new String(data, 0, 2, StandardCharsets.ISO_8859_1))) {// ZIP\n            try (ZipFile zipFile = new ZipFile(data)) {\n                ZipEntry classes = zipFile.findFirstEntry(\"classes.dex\");\n                if (classes != null) {\n                    return toByteArray(zipFile.getInputStream(classes));\n                } else {\n                    throw new IOException(\"Can not find classes.dex in zip file\");\n                }\n            }\n        }\n        throw new IOException(\"the src file not a .dex or zip file\");\n    }\n}\n","sourceCodeStart":67,"sourceCodeEnd":92,"githubUrl":"https://github.com/pxb1988/dex2jar/blob/b5bda4fb4935ae8b3869b422454ae3b3896c7bc1/dex-reader/src/main/java/com/googlecode/d2j/reader/zip/ZipUtil.java#L67-L92","documentation":"ZipUtil.readDex(byte[]) throws IOException when the input is a valid ZIP (PK prefix) but no entry named exactly \"classes.dex\" exists inside it. The method's contract is to return the raw bytes of classes.dex, so its absence is fatal.","triggerScenarios":"Calling ZipUtil.readDex on a zip whose entries do not include exactly \"classes.dex\" — e.g. multi-dex APKs where the helper is expected to be called per-entry, resource-only zips, or APKs with dex entries renamed/encrypted.","commonSituations":"Using readDex on an APK that only has classes2.dex+ (rare) or renamed dex entries; packed APKs that hide dex files until runtime; confusing readDex with MultiDexFileReader.open which accepts any *.dex entries.","solutions":["Use MultiDexFileReader.open(bytes) instead — it collects all classes*.dex entries.","Inspect the zip entries (zipFile entries list) to find the actual dex name.","Unpack the APK and pass the extracted classes.dex bytes directly as a raw dex (the dex branch returns data as-is).","If the APK is packed, dump runtime dex files and feed those."],"exampleFix":"// before\nbyte[] dex = ZipUtil.readDex(apkBytes); // fails if no classes.dex\n// after\nBaseDexFileReader r = MultiDexFileReader.open(apkBytes); // handles multi-dex","handlingStrategy":"try-catch","validationCode":"// confirm the exact entry exists before readDex\ntry (ZipFile zf = new ZipFile(data)) {\n    if (zf.findFirstEntry(\"classes.dex\") == null) {\n        throw new IllegalArgumentException(\"no classes.dex; use MultiDexFileReader.open for multi-dex\");\n    }\n}","typeGuard":null,"tryCatchPattern":"try {\n    byte[] dex = ZipUtil.readDex(apkBytes);\n} catch (IOException e) {\n    LOG.warn(\"classes.dex missing, falling back to multi-dex reader\");\n    BaseDexFileReader r = MultiDexFileReader.open(apkBytes);\n}","preventionTips":["Prefer MultiDexFileReader.open over ZipUtil.readDex for APKs (handles all dex entries)","List zip entries to confirm entry naming/casing","For packed APKs, extract runtime dex before extraction"],"tags":["dex","android","zip","apk"],"backgroundTag":"resource-not-found","analyzedSha":"b5bda4fb4935ae8b3869b422454ae3b3896c7bc1","analyzedAt":"2026-09-08T00:44:01.258Z","contentChangedAt":"2026-09-08T00:44:01.258Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}