{"record":{"id":"07cd39ff94397ec3","repo":"asLody/VirtualApp","slug":"dex2oat-works-unsuccessfully-exit-code-ret","errorCode":null,"errorMessage":"dex2oat works unsuccessfully, exit code: ${ret}","messagePattern":"dex2oat works unsuccessfully, exit code: (.+?)","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"warning","filePath":"VirtualApp/lib/src/main/java/com/lody/virtual/helper/ArtDexOptimizer.java","lineNumber":59,"sourceCode":"        }\n        commandAndParams.add(\"--dex-file=\" + dexFilePath);\n        commandAndParams.add(\"--oat-file=\" + oatFilePath);\n        commandAndParams.add(\"--instruction-set=\" + VMRuntime.getCurrentInstructionSet.call());\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    }\n\n    private static class StreamConsumer {\n        static final Executor STREAM_CONSUMER = Executors.newSingleThreadExecutor();\n\n        static void consumeInputStream(final InputStream is) {\n            STREAM_CONSUMER.execute(new Runnable() {\n                @Override\n                public void run() {\n                    if (is == null) {\n                        return;\n                    }\n                    final byte[] buffer = new byte[256];\n                    try {","sourceCodeStart":41,"sourceCodeEnd":77,"githubUrl":"https://github.com/asLody/VirtualApp/blob/666fefcb5d3f39cc944001c3457c38ffd6544c87/VirtualApp/lib/src/main/java/com/lody/virtual/helper/ArtDexOptimizer.java#L41-L77","documentation":"ArtDexOptimizer.interpretDex2Oat shells out to the dex2oat binary to compile the plugin's dex into OAT/odex. If the dex2oat process exits with a non-zero status, the library throws this IOException, meaning the plugin's native compilation failed (though the app may still run in interpreter mode).","triggerScenarios":"dex2oat exits non-zero: unsupported dex bytecode, corrupted APK/dex, insufficient disk space in the OAT output directory, incompatible dex2oat version on the device ROM, or invalid compiler flags.","commonSituations":"Custom ROMs with a broken/missing dex2oat; Android version mismatch between dex flags and the ART version; out-of-space on /data; plugin APK containing desugared/preview bytecode the device dex2oat can't handle.","solutions":["Check the dex2oat stderr output (consumed by StreamConsumer) by rerunning the dex2oat command manually for the real failure reason","Disable/relax OAT compilation so the plugin runs via interpreter fallback (skip optimize) — the app usually still works","Free disk space in the plugin data/OAT directory and retry","Verify the plugin APK's dex is valid and the device ROM's dex2oat supports it"],"exampleFix":"// before\n// throws and aborts when dex2oat fails\nArtDexOptimizer.interpretDex2Oat(dexPath, oatPath, ...);\n// after\ntry {\n    ArtDexOptimizer.interpretDex2Oat(dexPath, oatPath, ...);\n} catch (IOException e) {\n    Log.w(TAG, \"dex2oat failed, falling back to interpreter mode\", e); // continue without OAT\n}","handlingStrategy":"fallback","validationCode":"File oatDir = new File(oatPath).getParentFile(); if (!oatDir.canWrite() || oatDir.getUsableSpace() < requiredBytes) { skipOptimization(); }","typeGuard":null,"tryCatchPattern":"try { ArtDexOptimizer.interpretDex2Oat(dex, oat, ...); } catch (IOException e) { Log.w(TAG, \"OAT skipped: \" + e.getMessage()); /* proceed in interpreter mode */ }","preventionTips":["Treat OAT optimization as best-effort; always allow interpreter-mode fallback","Monitor free disk space in the OAT output directory","Capture dex2oat stderr for diagnostics before discarding streams"],"tags":["android","dex2oat","art","compilation"],"backgroundTag":"http-request-failed","analyzedSha":"666fefcb5d3f39cc944001c3457c38ffd6544c87","analyzedAt":"2026-09-09T11:09:01.694Z","contentChangedAt":"2026-09-09T11:09:01.694Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}