{"record":{"id":"00a63959e173c26b","repo":"Tencent/tinker","slug":"dex2oat-works-unsuccessfully-exit-code","errorCode":null,"errorMessage":"dex2oat works unsuccessfully, exit code: ","messagePattern":"dex2oat works unsuccessfully, exit code: ","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"tinker-android/tinker-android-loader/src/main/java/com/tencent/tinker/loader/TinkerDexOptimizer.java","lineNumber":612,"sourceCode":"            }\n            commandAndParams.add(\"--dex-file=\" + dexFilePath);\n            commandAndParams.add(\"--oat-file=\" + oatFilePath);\n            commandAndParams.add(\"--instruction-set=\" + targetISA);\n            if (Build.VERSION.SDK_INT > 25) {\n                commandAndParams.add(\"--compiler-filter=quicken\");\n            } else {\n                commandAndParams.add(\"--compiler-filter=interpret-only\");\n            }\n\n            final ProcessBuilder pb = new ProcessBuilder(commandAndParams);\n            pb.redirectErrorStream(true);\n            final Process dex2oatProcess = pb.start();\n            StreamConsumer.consumeInputStream(dex2oatProcess.getInputStream());\n            StreamConsumer.consumeInputStream(dex2oatProcess.getErrorStream());\n            try {\n                final int ret = dex2oatProcess.waitFor();\n                if (ret != 0) {\n                    throw new IOException(\"dex2oat works unsuccessfully, exit code: \" + ret);\n                }\n            } catch (InterruptedException e) {\n                throw new IOException(\"dex2oat is interrupted, msg: \" + e.getMessage(), e);\n            }\n        } finally {\n            try {\n                if (fileLock != null) {\n                    fileLock.close();\n                }\n            } catch (IOException e) {\n                ShareTinkerLog.w(TAG, \"release interpret Lock error\", e);\n            }\n        }\n    }\n\n    private static class StreamConsumer {\n        static final Executor STREAM_CONSUMER = Executors.newSingleThreadExecutor();\n","sourceCodeStart":594,"sourceCodeEnd":630,"githubUrl":"https://github.com/Tencent/tinker/blob/1b7ea02c239840f563ea64fb5bd286eb98d4011e/tinker-android/tinker-android-loader/src/main/java/com/tencent/tinker/loader/TinkerDexOptimizer.java#L594-L630","documentation":"In interpret-mode fallback Tinker forks a dex2oat process directly (with --compiler-filter=interpret-only) and waits for it. This IOException means dex2oat exited with a non-zero status, so no usable odex was produced for the patched dex.","triggerScenarios":"dex2oat subprocess failing: corrupted or truncated patched dex, wrong dex2oat binary/arguments for the device's ART version, ISA mismatch (32/64-bit), or dex2oat crashing due to low memory or an unsupported dex feature in the patch.","commonSituations":"Patch generated by an incompatible build-tools/gradle-plugin version; proguard/R8 output that the on-device dex2oat cannot process; Android 12+ where dex2oat flag sets changed; multi-dex patches where one fragment is bad.","solutions":["Regenerate the patch with the Tinker gradle plugin version matching the Tinker SDK in use.","Validate the patched dex (dexdump / rebuilt with same build-tools) and confirm the app builds and runs the same classes unpatched.","Capture StreamConsumer output for dex2oat (adb logcat) to get the exact reason for the non-zero exit.","If the failure is device-specific (ISA or ART flag change), update Tinker, which carries per-OS dex2oat argument fixes."],"exampleFix":null,"handlingStrategy":"fallback","validationCode":"// Before loading: sanity-check extracted dex files\nfor (File dex : patchDexDir.listFiles()) {\n    if (dex.length() == 0 || !SharePatchFileUtil.verifyDexFileMd5(dex, expected)) {\n        rejectPatch();\n    }\n}","typeGuard":null,"tryCatchPattern":"try {\n    runDex2oatInterpretOnly(dexFile, oatFile);\n} catch (IOException e) {\n    // dex2oat failed: run the dex purely interpreted (no odex needed)\n    DexExtractHelper.loadDexInterpreted(classLoader, dexFile);\n}","preventionTips":["Always verify patch package checksums before extraction and load.","Keep gradle plugin and Tinker SDK versions in lockstep.","Enable Tinker's patch verification (tinkerLoadVerifyFlag) in production."],"tags":["android","dex2oat","interpret-mode","art","tinker"],"backgroundTag":null,"analyzedSha":"1b7ea02c239840f563ea64fb5bd286eb98d4011e","analyzedAt":"2026-08-14T15:16:52.110Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}