skylot/jadx · error · JadxRuntimeException

Failed to save mapping json

Error message

Failed to save mapping json

What it means

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.

Source

Thrown at jadx-core/src/main/java/jadx/core/codegen/json/JsonMappingGen.java:50

	private static final Gson GSON = GsonUtils.defaultGsonBuilder()
			.setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_DASHES)
			.disableHtmlEscaping()
			.create();

	public static void dump(RootNode root) {
		JsonMapping mapping = new JsonMapping();
		fillMapping(mapping, root);

		JadxArgs args = root.getArgs();
		File outDirSrc = args.getOutDirSrc().getAbsoluteFile();
		File mappingFile = new File(outDirSrc, "mapping.json");
		FileUtils.makeDirsForFile(mappingFile);
		try (Writer writer = new FileWriter(mappingFile)) {
			GSON.toJson(mapping, writer);
			LOG.info("Save mappings to {}", mappingFile.getAbsolutePath());
		} catch (Exception e) {
			throw new JadxRuntimeException("Failed to save mapping json", e);
		}
	}

	private static void fillMapping(JsonMapping mapping, RootNode root) {
		List<ClassNode> classes = root.getClasses(true);
		mapping.setClasses(new ArrayList<>(classes.size()));
		for (ClassNode cls : classes) {
			ClassInfo classInfo = cls.getClassInfo();
			JsonClsMapping jsonCls = new JsonClsMapping();
			jsonCls.setName(classInfo.getRawName());
			jsonCls.setAlias(classInfo.getAliasFullName());
			jsonCls.setInner(classInfo.isInner());
			jsonCls.setJson(cls.getTopParentClass().getClassInfo().getAliasFullPath() + ".json");
			if (classInfo.isInner()) {
				jsonCls.setTopClass(cls.getTopParentClass().getClassInfo().getFullName());
			}
			addFields(cls, jsonCls);
			addMethods(cls, jsonCls);

View on GitHub (pinned to e738a26571)

Solutions

  1. Check the caused-by exception: IOException => filesystem/permission; JsonIOException/StackOverflowError => serialisation problem.
  2. Verify outDirSrc exists and is writable (FileUtils.makeDirsForFile is called just above, so the parent should exist - check permissions/disk).
  3. Ensure no other process holds mapping.json open exclusively (close other jadx instances).
  4. If GSON is the cause, inspect the JsonMapping object for circular refs or null fields and fix the model.
  5. Free disk space and retry.

Example fix

// before
try (Writer writer = new FileWriter(mappingFile)) {
    GSON.toJson(mapping, writer);
    LOG.info("Save mappings to {}", mappingFile.getAbsolutePath());
} catch (Exception e) {
    throw new JadxRuntimeException("Failed to save mapping json", e);
}

// after (report the precise path and cause, and use explicit charset)
try (Writer writer = new OutputStreamWriter(new FileOutputStream(mappingFile), StandardCharsets.UTF_8)) {
    GSON.toJson(mapping, writer);
    LOG.info("Save mappings to {}", mappingFile.getAbsolutePath());
} catch (IOException e) {
    throw new JadxRuntimeException("Failed to write mapping.json to " + mappingFile.getAbsolutePath(), e);
} catch (JsonIOException e) {
    throw new JadxRuntimeException("Failed to serialise mapping.json", e);
}
Defensive patterns

Strategy: validation

Validate before calling

File outDirSrc = args.getOutDirSrc().getAbsoluteFile();
File mappingFile = new File(outDirSrc, "mapping.json");
if (!outDirSrc.exists() && !outDirSrc.mkdirs()) {
    throw new IOException("Cannot create output dir: " + outDirSrc);
}
if (!outDirSrc.canWrite()) {
    throw new IOException("Output dir not writable: " + outDirSrc);
}

Type guard

null

Try / catch

try {
    JsonMappingGen.dump(root);
} catch (JadxRuntimeException e) {
    Throwable cause = e.getCause();
    if (cause instanceof IOException) {
        LOG.error("Filesystem error writing mapping.json: {}", cause.getMessage());
    } else {
        LOG.error("Serialisation error writing mapping.json", e);
    }
}

Prevention

When it happens

Trigger: 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).

Common situations: 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.

Related errors


AI-assisted analysis of skylot/jadx@e738a26571 (2026-08-14). Data as JSON: /api/errors/d99739c224bf13c7. Report an issue: GitHub.