{"record":{"id":"4d91f47232e91fad","repo":"skylot/jadx","slug":"duplicate-class","errorCode":null,"errorMessage":"Duplicate class: ","messagePattern":"Duplicate class: ","errorType":"exception","errorClass":"JadxRuntimeException","httpStatus":null,"severity":"error","filePath":"jadx-core/src/main/java/jadx/core/clsp/ClsSet.java","lineNumber":102,"sourceCode":"\t\t\tint methodsCount = Stream.of(classes).mapToInt(clspClass -> clspClass.getMethodsMap().size()).sum();\n\t\t\tLOG.debug(\"Clst file loaded in {}ms, android api: {}, classes: {}, methods: {}\",\n\t\t\t\t\ttime, androidApiLevel, classes.length, methodsCount);\n\t\t}\n\t}\n\n\tpublic void loadFrom(RootNode root) {\n\t\tList<ClassNode> list = root.getClasses(true);\n\t\tMap<String, ClspClass> names = new HashMap<>(list.size());\n\t\tint k = 0;\n\t\tfor (ClassNode cls : list) {\n\t\t\tArgType clsType = cls.getClassInfo().getType();\n\t\t\tString clsRawName = clsType.getObject();\n\t\t\tcls.load();\n\n\t\t\tClspClassSource source = getClspClassSource(cls);\n\t\t\tClspClass nClass = new ClspClass(clsType, k, cls.getAccessFlags().rawValue(), source);\n\t\t\tif (names.put(clsRawName, nClass) != null) {\n\t\t\t\tthrow new JadxRuntimeException(\"Duplicate class: \" + clsRawName);\n\t\t\t}\n\t\t\tk++;\n\t\t\tnClass.setTypeParameters(cls.getGenericTypeParameters());\n\t\t\tnClass.setMethods(getMethodsDetails(cls));\n\t\t}\n\t\tclasses = new ClspClass[k];\n\t\tk = 0;\n\t\tfor (ClassNode cls : list) {\n\t\t\tClspClass nClass = getCls(cls, names);\n\t\t\tif (nClass == null) {\n\t\t\t\tthrow new JadxRuntimeException(\"Missing class: \" + cls);\n\t\t\t}\n\t\t\tnClass.setParents(makeParentsArray(cls));\n\t\t\tclasses[k] = nClass;\n\t\t\tk++;\n\t\t}\n\t}\n","sourceCodeStart":84,"sourceCodeEnd":120,"githubUrl":"https://github.com/skylot/jadx/blob/e738a26571d02919f01df40de93bc9a44dee4e18/jadx-core/src/main/java/jadx/core/clsp/ClsSet.java#L84-L120","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Pre-deduplicate classes by raw name before calling loadFrom\nList<ClassNode> classes = root.getClasses(true);\nMap<String, ClassNode> deduped = new LinkedHashMap<>();\nfor (ClassNode cls : classes) {\n    String name = cls.getClassInfo().getType().getObject();\n    deduped.putIfAbsent(name, cls);\n}\n// Check for duplicates\nif (deduped.size() < classes.size()) {\n    throw new IllegalStateException(\"Duplicate class names detected in input\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    clsSet.loadFrom(root);\n} catch (JadxRuntimeException e) {\n    if (e.getMessage().startsWith(\"Duplicate class:\")) {\n        String className = e.getMessage().substring(\"Duplicate class: \".length());\n        LOG.warn(\"Skipping duplicate class: {}\", className);\n        // remove duplicate and retry\n    } else {\n        throw e;\n    }\n}","preventionTips":["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."],"tags":["classpath","clst","duplicate","class-processing"],"backgroundTag":null,"analyzedSha":"e738a26571d02919f01df40de93bc9a44dee4e18","analyzedAt":"2026-08-14T00:10:24.238Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}