skylot/jadx · error · JadxRuntimeException
Duplicate class:
Error message
Duplicate class:
What it means
Thrown by ClsSet.loadFrom when two classes in the input root have the same raw type name. The method iterates root.getClasses(true), builds a map keyed by ArgType.getObject() (the class's internal raw name), and throws if names.put returns a non-null previous value. This indicates a genuine collision in the input set being exported to the classpath format.
Source
Thrown at jadx-core/src/main/java/jadx/core/clsp/ClsSet.java:102
int methodsCount = Stream.of(classes).mapToInt(clspClass -> clspClass.getMethodsMap().size()).sum();
LOG.debug("Clst file loaded in {}ms, android api: {}, classes: {}, methods: {}",
time, androidApiLevel, classes.length, methodsCount);
}
}
public void loadFrom(RootNode root) {
List<ClassNode> list = root.getClasses(true);
Map<String, ClspClass> names = new HashMap<>(list.size());
int k = 0;
for (ClassNode cls : list) {
ArgType clsType = cls.getClassInfo().getType();
String clsRawName = clsType.getObject();
cls.load();
ClspClassSource source = getClspClassSource(cls);
ClspClass nClass = new ClspClass(clsType, k, cls.getAccessFlags().rawValue(), source);
if (names.put(clsRawName, nClass) != null) {
throw new JadxRuntimeException("Duplicate class: " + clsRawName);
}
k++;
nClass.setTypeParameters(cls.getGenericTypeParameters());
nClass.setMethods(getMethodsDetails(cls));
}
classes = new ClspClass[k];
k = 0;
for (ClassNode cls : list) {
ClspClass nClass = getCls(cls, names);
if (nClass == null) {
throw new JadxRuntimeException("Missing class: " + cls);
}
nClass.setParents(makeParentsArray(cls));
classes[k] = nClass;
k++;
}
}
View on GitHub (pinned to e738a26571)
Solutions
- Identify and remove the duplicate class from one of the input sources before running ClsSet.loadFrom.
- For multi-dex inputs, use jadx's deduplication options or check if a class is legitimately duplicated and exclude the redundant copy.
- Inspect the class name in the error message and search the input APKs/JARs for that class to locate both sources.
- If this occurs during a custom jadx-based tool, filter the root's class list to unique names before calling loadFrom.
Defensive patterns
Strategy: validation
Validate before calling
// Pre-deduplicate classes by raw name before calling loadFrom
List<ClassNode> classes = root.getClasses(true);
Map<String, ClassNode> deduped = new LinkedHashMap<>();
for (ClassNode cls : classes) {
String name = cls.getClassInfo().getType().getObject();
deduped.putIfAbsent(name, cls);
}
// Check for duplicates
if (deduped.size() < classes.size()) {
throw new IllegalStateException("Duplicate class names detected in input");
} Try / catch
try {
clsSet.loadFrom(root);
} catch (JadxRuntimeException e) {
if (e.getMessage().startsWith("Duplicate class:")) {
String className = e.getMessage().substring("Duplicate class: ".length());
LOG.warn("Skipping duplicate class: {}", className);
// remove duplicate and retry
} else {
throw e;
}
} Prevention
- Deduplicate class inputs by raw name before building the ClsSet.
- For multi-dex inputs, identify and remove duplicate classes from redundant dex files.
- Search the input APK/JARs for the duplicate class name to locate both sources.
When it happens
Trigger: Calling ClsSet.loadFrom(root) where the RootNode contains two ClassNodes resolving to the same raw class name (e.g., 'com.example.Foo' appearing in two different input files). This can happen with multi-dex inputs that contain duplicate class definitions, or when processing an APK with overlapping library JARs.
Common situations: Decompiling a multi-dex APK where the same class is duplicated across dex files (sometimes due to build tooling issues). Running the classpath export (e.g., via jadx-cli export or internal ClsSet.save) on an input with bundled duplicate libraries. Obfuscated inputs where renaming causes name collisions after processing.
Related errors
- Missing class:
- Can't load classpath file:
- Unexpected input file:
- Unknown file format:
- Cannot save type:
AI-assisted analysis of skylot/jadx@e738a26571 (2026-08-14).
Data as JSON: /api/errors/4d91f47232e91fad.
Report an issue: GitHub.