skylot/jadx · error · JadxRuntimeException
Failed to load top level domain list file: tlds.txt
Error message
Failed to load top level domain list file: tlds.txt
What it means
Thrown when the bundled resource tlds.txt cannot be loaded from the classpath by ExcludePackageWithTLDNames (a deobfuscation condition that prevents renaming packages whose name is a top-level domain). It is loaded once, lazily, via a static-holder idiom. Any failure opening/reading the resource aborts initialisation.
Source
Thrown at jadx-core/src/main/java/jadx/core/deobf/conditions/ExcludePackageWithTLDNames.java:29
/**
* Provides a list of all top level domains, so we can exclude them from deobfuscation.
*/
public class ExcludePackageWithTLDNames extends AbstractDeobfCondition {
/**
* Lazy load TLD set
*/
private static class TldHolder {
private static final Set<String> TLD_SET = loadTldSet();
}
private static Set<String> loadTldSet() {
try (BufferedReader reader = new BufferedReader(new InputStreamReader(TldHolder.class.getResourceAsStream("tlds.txt")))) {
return reader.lines()
.filter(line -> !line.startsWith("#") && !line.isEmpty())
.collect(Collectors.toSet());
} catch (Exception e) {
throw new JadxRuntimeException("Failed to load top level domain list file: tlds.txt", e);
}
}
@Override
public Action check(PackageNode pkg) {
if (pkg.isRoot() && TldHolder.TLD_SET.contains(pkg.getName())) {
return Action.FORBID_RENAME;
}
return Action.NO_ACTION;
}
}
View on GitHub (pinned to e738a26571)
Solutions
- Use the official, complete jadx distribution where tlds.txt ships alongside the class.
- If repackaging, ensure resources under jadx/core/deobf/conditions/ are included (verify with: jar tf jadx-core.jar | grep tlds.txt).
- Guard against null stream: getResourceAsStream can return null - wrap with Objects.requireNonNull and give a clearer message, or fall back to an empty set.
- If embedding in another app, use a parent-first classloader or load the resource explicitly via the jadx-core classloader.
Example fix
// before
try (BufferedReader reader = new BufferedReader(new InputStreamReader(TldHolder.class.getResourceAsStream("tlds.txt")))) {
return reader.lines().filter(line -> !line.startsWith("#") && !line.isEmpty()).collect(Collectors.toSet());
} catch (Exception e) {
throw new JadxRuntimeException("Failed to load top level domain list file: tlds.txt", e);
}
// after (handle null stream + explicit charset, degrade gracefully)
InputStream is = TldHolder.class.getResourceAsStream("tlds.txt");
if (is == null) {
LOG.warn("tlds.txt not found on classpath; TLD exclusion disabled");
return Collections.emptySet();
}
try (BufferedReader reader = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8))) {
return reader.lines().filter(line -> !line.startsWith("#") && !line.isEmpty()).collect(Collectors.toSet());
} catch (IOException e) {
throw new JadxRuntimeException("Failed to load top level domain list file: tlds.txt", e);
} Defensive patterns
Strategy: fallback
Validate before calling
InputStream is = ExcludePackageWithTLDNames.class.getResourceAsStream("tlds.txt");
if (is == null) {
LOG.warn("tlds.txt missing from classpath; TLD exclusion will be disabled");
} Type guard
null
Try / catch
// Static init failures are hard to catch; isolate the load behind a lazy holder
// and catch at first use:
Set<String> tlds;
try {
tlds = TldHolder.TLD_SET;
} catch (ExceptionInInitializerError e) {
LOG.warn("TLD list unavailable, disabling rule", e);
tlds = Collections.emptySet();
} Prevention
- Use a complete, official jadx distribution that bundles resources.
- When shading jadx, include resources under jadx/core/deobf/conditions/.
- Verify with: jar tf jadx-core.jar | grep tlds.txt before deploying.
- Make the loader null-tolerant so a missing resource degrades rather than crashes.
When it happens
Trigger: The resource jadx-core/.../conditions/tlds.txt is missing from the classpath/jar, getResourceAsStream returns null (NullPointerException inside the try), or the stream throws while reading. Happens if the jadx-core jar is repackaged/shaded and resources are stripped, or if the file is corrupted.
Common situations: Custom/shaded packaging of jadx that drops resources; building jadx from a partial checkout; classloader isolation (e.g. embedding jadx in another app with a non-standard classloader that does not expose sibling resources); corrupted jar download.
Related errors
- {} not found in classpath
- Can't load classpath file:
- Failed to load android resource file (res-map.txt)
- Xml load error, file: {}
- Failed to init res table provider: ${resTableParserProvider}
AI-assisted analysis of skylot/jadx@e738a26571 (2026-08-14).
Data as JSON: /api/errors/d6e3c663eb92ec6b.
Report an issue: GitHub.