{"record":{"id":"f542993e36937744","repo":"skylot/jadx","slug":"failed-to-load-config-file","errorCode":null,"errorMessage":"Failed to load config file: {}","messagePattern":"Failed to load config file: (.+?)","errorType":"exception","errorClass":"JadxRuntimeException","httpStatus":null,"severity":"error","filePath":"jadx-cli/src/main/java/jadx/cli/config/JadxConfigAdapter.java","lineNumber":73,"sourceCode":"\t}\n\n\tpublic Path getConfigPath() {\n\t\treturn configPath;\n\t}\n\n\tpublic String getDefaultConfigFileName() {\n\t\treturn defaultConfigFileName;\n\t}\n\n\tpublic @Nullable T load() {\n\t\tif (!Files.isRegularFile(configPath)) {\n\t\t\t// file not found\n\t\t\treturn null;\n\t\t}\n\t\ttry (JsonReader reader = gson.newJsonReader(Files.newBufferedReader(configPath))) {\n\t\t\treturn gson.fromJson(reader, configCls);\n\t\t} catch (Exception e) {\n\t\t\tthrow new JadxRuntimeException(\"Failed to load config file: \" + configPath, e);\n\t\t}\n\t}\n\n\tpublic void save(T configObject) {\n\t\ttry {\n\t\t\tString jsonStr = gson.toJson(configObject, configCls);\n\t\t\t// don't use stream writer here because serialization errors will corrupt config\n\t\t\tFiles.writeString(configPath, jsonStr);\n\t\t} catch (Exception e) {\n\t\t\tthrow new JadxRuntimeException(\"Failed to save config file: \" + configPath, e);\n\t\t}\n\t}\n\n\tpublic String objectToJsonString(T configObject) {\n\t\treturn gson.toJson(configObject, configCls);\n\t}\n\n\tpublic T jsonStringToObject(String jsonStr) {","sourceCodeStart":55,"sourceCodeEnd":91,"githubUrl":"https://github.com/skylot/jadx/blob/e738a26571d02919f01df40de93bc9a44dee4e18/jadx-cli/src/main/java/jadx/cli/config/JadxConfigAdapter.java#L55-L91","documentation":"Thrown by SmaliDebugger.handShake when writing the JDWP handshake bytes to the output stream or reading the 14-byte handshake reply from the input stream raises any exception (it catches broad Exception). It means the underlying transport failed during the JDWP handshake exchange itself: the peer reset the connection, the stream hit EOF, or the 5-second socket timeout elapsed before 14 bytes arrived.","triggerScenarios":"handShake writes JDWP.encodeHandShakePacket() then IOUtils.readNBytes(in, 14). A connection reset, EOF, or socket-read timeout during that exchange is wrapped here. Fires at the very start of initJDWP, before any command packets are sent.","commonSituations":"The forwarded port has no jdwp listener (immediate reset), the target process died mid-handshake, the device USB link dropped, the socket timeout (5000ms) is too short for a slow device, or another client already consumed the jdwp endpoint.","solutions":["Re-establish the ADB jdwp forward for the live process id and retry attach.","Confirm the target app/process is still alive at attach time (not yet crashed or exited).","Make sure only one debugger attaches; jdwp accepts a single handshake client per session.","Inspect the wrapped cause: SocketException/EOFException points to a dead/unreachable peer, SocketTimeoutException to a slow/unresponsive one."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// Before attach, confirm a TCP peer is listening and is a jdwp agent:\ntry (Socket s = new Socket()) {\n    s.connect(new InetSocketAddress(host, port), 2000);\n    s.setSoTimeout(2000);\n    s.getOutputStream().write(JDWP.encodeHandShakePacket());\n    byte[] reply = IOUtils.readNBytes(s.getInputStream(), 14);\n    if (reply == null || !JDWP.decodeHandShakePacket(reply)) {\n        throw new IllegalStateException(\"No jdwp agent on \" + host + \":\" + port);\n    }\n}","typeGuard":null,"tryCatchPattern":"// handShake runs inside attach; handle at the attach boundary\ntry {\n    return SmaliDebugger.attach(host, port, listener);\n} catch (SmaliDebuggerException e) {\n    Throwable cause = e.getCause();\n    boolean transientNet = cause instanceof java.net.SocketTimeoutException\n        || cause instanceof java.net.SocketException\n        || cause instanceof java.io.EOFException;\n    if (transientNet) {\n        ensureJdwpForward(packageName, port);\n        return SmaliDebugger.attach(host, port, listener); // retry once\n    }\n    throw e;\n}","preventionTips":["Establish the jdwp forward fresh right before attach.","Attach while the target process is alive; re-attach if it restarted.","Use a single debugger per jdwp session.","Differentiate refused/EOF (dead peer) from timeout (slow peer) via the wrapped cause."],"tags":["debugger","jdwp","handshake","network","adb"],"backgroundTag":null,"analyzedSha":"e738a26571d02919f01df40de93bc9a44dee4e18","analyzedAt":"2026-08-14T00:10:24.238Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}