{"record":{"id":"d99739c224bf13c7","repo":"skylot/jadx","slug":"failed-to-save-mapping-json","errorCode":null,"errorMessage":"Failed to save mapping json","messagePattern":"Failed to save mapping json","errorType":"exception","errorClass":"JadxRuntimeException","httpStatus":null,"severity":"error","filePath":"jadx-core/src/main/java/jadx/core/codegen/json/JsonMappingGen.java","lineNumber":50,"sourceCode":"\n\tprivate static final Gson GSON = GsonUtils.defaultGsonBuilder()\n\t\t\t.setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_DASHES)\n\t\t\t.disableHtmlEscaping()\n\t\t\t.create();\n\n\tpublic static void dump(RootNode root) {\n\t\tJsonMapping mapping = new JsonMapping();\n\t\tfillMapping(mapping, root);\n\n\t\tJadxArgs args = root.getArgs();\n\t\tFile outDirSrc = args.getOutDirSrc().getAbsoluteFile();\n\t\tFile mappingFile = new File(outDirSrc, \"mapping.json\");\n\t\tFileUtils.makeDirsForFile(mappingFile);\n\t\ttry (Writer writer = new FileWriter(mappingFile)) {\n\t\t\tGSON.toJson(mapping, writer);\n\t\t\tLOG.info(\"Save mappings to {}\", mappingFile.getAbsolutePath());\n\t\t} catch (Exception e) {\n\t\t\tthrow new JadxRuntimeException(\"Failed to save mapping json\", e);\n\t\t}\n\t}\n\n\tprivate static void fillMapping(JsonMapping mapping, RootNode root) {\n\t\tList<ClassNode> classes = root.getClasses(true);\n\t\tmapping.setClasses(new ArrayList<>(classes.size()));\n\t\tfor (ClassNode cls : classes) {\n\t\t\tClassInfo classInfo = cls.getClassInfo();\n\t\t\tJsonClsMapping jsonCls = new JsonClsMapping();\n\t\t\tjsonCls.setName(classInfo.getRawName());\n\t\t\tjsonCls.setAlias(classInfo.getAliasFullName());\n\t\t\tjsonCls.setInner(classInfo.isInner());\n\t\t\tjsonCls.setJson(cls.getTopParentClass().getClassInfo().getAliasFullPath() + \".json\");\n\t\t\tif (classInfo.isInner()) {\n\t\t\t\tjsonCls.setTopClass(cls.getTopParentClass().getClassInfo().getFullName());\n\t\t\t}\n\t\t\taddFields(cls, jsonCls);\n\t\t\taddMethods(cls, jsonCls);","sourceCodeStart":32,"sourceCodeEnd":68,"githubUrl":"https://github.com/skylot/jadx/blob/e738a26571d02919f01df40de93bc9a44dee4e18/jadx-core/src/main/java/jadx/core/codegen/json/JsonMappingGen.java#L32-L68","documentation":"Thrown by JsonMappingGen.dump when writing mapping.json to disk fails for any reason (I/O error, serialisation error, or GSON failure). The original exception is wrapped. The output directory must already be writable.","triggerScenarios":"Calling JsonMappingGen.dump (triggered by JSON mapping export) when the target file mapping.json under args.getOutDirSrc() cannot be written: missing directory, read-only location, disk full, permission denied, or an object in the mapping graph that GSON cannot serialise (circular reference, non-serialisable field).","commonSituations":"Output directory not created or lacking write permissions; running jadx read-only / in a sandbox without filesystem access; path too long; concurrent runs writing the same file; GSON hitting an unserialisable node in the mapping model.","solutions":["Check the caused-by exception: IOException => filesystem/permission; JsonIOException/StackOverflowError => serialisation problem.","Verify outDirSrc exists and is writable (FileUtils.makeDirsForFile is called just above, so the parent should exist - check permissions/disk).","Ensure no other process holds mapping.json open exclusively (close other jadx instances).","If GSON is the cause, inspect the JsonMapping object for circular refs or null fields and fix the model.","Free disk space and retry."],"exampleFix":"// before\ntry (Writer writer = new FileWriter(mappingFile)) {\n    GSON.toJson(mapping, writer);\n    LOG.info(\"Save mappings to {}\", mappingFile.getAbsolutePath());\n} catch (Exception e) {\n    throw new JadxRuntimeException(\"Failed to save mapping json\", e);\n}\n\n// after (report the precise path and cause, and use explicit charset)\ntry (Writer writer = new OutputStreamWriter(new FileOutputStream(mappingFile), StandardCharsets.UTF_8)) {\n    GSON.toJson(mapping, writer);\n    LOG.info(\"Save mappings to {}\", mappingFile.getAbsolutePath());\n} catch (IOException e) {\n    throw new JadxRuntimeException(\"Failed to write mapping.json to \" + mappingFile.getAbsolutePath(), e);\n} catch (JsonIOException e) {\n    throw new JadxRuntimeException(\"Failed to serialise mapping.json\", e);\n}","handlingStrategy":"validation","validationCode":"File outDirSrc = args.getOutDirSrc().getAbsoluteFile();\nFile mappingFile = new File(outDirSrc, \"mapping.json\");\nif (!outDirSrc.exists() && !outDirSrc.mkdirs()) {\n    throw new IOException(\"Cannot create output dir: \" + outDirSrc);\n}\nif (!outDirSrc.canWrite()) {\n    throw new IOException(\"Output dir not writable: \" + outDirSrc);\n}","typeGuard":"null","tryCatchPattern":"try {\n    JsonMappingGen.dump(root);\n} catch (JadxRuntimeException e) {\n    Throwable cause = e.getCause();\n    if (cause instanceof IOException) {\n        LOG.error(\"Filesystem error writing mapping.json: {}\", cause.getMessage());\n    } else {\n        LOG.error(\"Serialisation error writing mapping.json\", e);\n    }\n}","preventionTips":["Pre-create and verify the output directory is writable before export.","Close other jadx instances writing the same file.","Check disk space for large mappings.","Ensure the JsonMapping graph has no circular references if serialisation fails."],"tags":["json","io","filesystem","mapping"],"backgroundTag":null,"analyzedSha":"e738a26571d02919f01df40de93bc9a44dee4e18","analyzedAt":"2026-08-14T00:10:24.238Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}