{"record":{"id":"a4983a9df0fb295b","repo":"skylot/jadx","slug":"no-end-types-in-class-hierarchy","errorCode":null,"errorMessage":"No end types in class hierarchy: {}","messagePattern":"No end types in class hierarchy: (.+?)","errorType":"exception","errorClass":"JadxRuntimeException","httpStatus":null,"severity":"error","filePath":"jadx-core/src/main/java/jadx/core/dex/visitors/OverrideMethodVisitor.java","lineNumber":292,"sourceCode":"\t\tpublic List<ArgType> getSuperTypes() {\n\t\t\treturn superTypes;\n\t\t}\n\n\t\tpublic Set<String> getEndTypes() {\n\t\t\treturn endTypes;\n\t\t}\n\t}\n\n\t@Nullable\n\tprivate SuperTypesData collectSuperTypes(ClassNode cls) {\n\t\tSet<ArgType> superTypes = new LinkedHashSet<>();\n\t\tSet<String> endTypes = new HashSet<>();\n\t\tcollectSuperTypes(cls, superTypes, endTypes);\n\t\tif (superTypes.isEmpty()) {\n\t\t\treturn null;\n\t\t}\n\t\tif (endTypes.isEmpty()) {\n\t\t\tthrow new JadxRuntimeException(\"No end types in class hierarchy: \" + cls);\n\t\t}\n\t\treturn new SuperTypesData(new ArrayList<>(superTypes), endTypes);\n\t}\n\n\tprivate void collectSuperTypes(ClassNode cls, Set<ArgType> superTypes, Set<String> endTypes) {\n\t\tRootNode root = cls.root();\n\t\tint k = 0;\n\t\tArgType superClass = cls.getSuperClass();\n\t\tif (superClass != null) {\n\t\t\tk += addSuperType(root, superTypes, endTypes, superClass);\n\t\t}\n\t\tfor (ArgType iface : cls.getInterfaces()) {\n\t\t\tk += addSuperType(root, superTypes, endTypes, iface);\n\t\t}\n\t\tif (k == 0) {\n\t\t\tendTypes.add(cls.getType().getObject());\n\t\t}\n\t}","sourceCodeStart":274,"sourceCodeEnd":310,"githubUrl":"https://github.com/skylot/jadx/blob/e738a26571d02919f01df40de93bc9a44dee4e18/jadx-core/src/main/java/jadx/core/dex/visitors/OverrideMethodVisitor.java#L274-L310","documentation":"Thrown during override-method analysis when collecting supertypes of a class. The visitor traverses the class hierarchy gathering both supertypes and 'end types' (terminal leaves of the hierarchy graph, e.g., java.lang.Object or unknown external classes). If at least one supertype was collected but zero end types were identified, the hierarchy graph is malformed or circular in a way that prevents resolving method overrides.","triggerScenarios":"collectSuperTypes found non-empty superTypes but empty endTypes. This happens when every supertype encountered was already in the superTypes set (via addSuperType's loop detection returning 0) before any terminal end type was recorded, or when resolved ClassNodes form a cycle that exhausts before reaching a leaf.","commonSituations":"Obfuscated APKs with intentionally circular class hierarchies crafted by tools that rewrite superclass references; partial DEX inputs where referenced superclass definitions are missing from both the input and the jadx classpath (clsp); class hierarchies that reference themselves as a superclass.","solutions":["Ensure all referenced superclass/interface DEX files are included in the input set so jadx can resolve them","Update jadx to the latest version — class hierarchy analysis is actively improved","Report the APK with the failing class name as a jadx GitHub issue for a fix","As a workaround, mark the problem class with DONT_GENERATE via a custom pass or exclude it from input"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// Before batch decompilation, verify all input DEX files are present\nFile[] inputFiles = new File(apkDir).listFiles((d, f) -> f.endsWith(\".dex\"));\nif (inputFiles == null || inputFiles.length == 0) {\n    throw new IllegalArgumentException(\"No DEX files found in input\");\n}\n// Load with all classpath dependencies to maximize hierarchy resolution\nJadxArgs args = new JadxArgs();\nargs.setInputFiles(Arrays.asList(inputFiles));","typeGuard":null,"tryCatchPattern":"try {\n    jadxDecompiler.load();\n    jadxDecompiler.save();\n} catch (JadxRuntimeException e) {\n    if (e.getMessage().contains(\"No end types in class hierarchy\")) {\n        LOG.warn(\"Class hierarchy issue in input, skipping full decompile: {}\", e.getMessage());\n        // Retry with per-class decompilation to isolate the problem\n    } else {\n        throw e;\n    }\n}","preventionTips":["Include all DEX files from multidex APKs as input together","Provide the jadx classpath JAR (android.jar) to resolve external class hierarchies","Keep jadx updated to benefit from hierarchy analysis improvements","Use per-class decompilation (decompileClass) instead of batch save to isolate failures"],"tags":["class-hierarchy","override-analysis","type-resolution","obfuscation","decompiler"],"backgroundTag":null,"analyzedSha":"e738a26571d02919f01df40de93bc9a44dee4e18","analyzedAt":"2026-08-14T00:10:24.238Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}