Tencent/tinker · critical · TinkerRuntimeException
Fail to create TinkerClassLoader.
Error message
Fail to create TinkerClassLoader.
What it means
TinkerClassLoader's constructor splits the dexPath on ':', collects non-empty File entries, and calls SystemClassLoaderAdder.injectDexesInternal to install them into the delegate classloader (which dispatches to V23/V19/V14 per SDK). Any throwable from that injection is wrapped in TinkerRuntimeException('Fail to create TinkerClassLoader.'). It is the aggregate failure point for dex injection on the tinker classloader path.
Source
Thrown at tinker-android/tinker-android-loader/src/main/java/com/tencent/tinker/loader/TinkerClassLoader.java:87
mOriginAppClassLoader.getResources(name)
};
return new CompoundEnumeration<>(resources);
}
private static void injectDexPath(ClassLoader cl, String dexPath, File optimizedDir) {
try {
final List<File> dexFiles = new ArrayList<>(16);
for (String oneDexPath : dexPath.split(":")) {
if (oneDexPath.isEmpty()) {
continue;
}
dexFiles.add(new File(oneDexPath));
}
if (!dexFiles.isEmpty()) {
SystemClassLoaderAdder.injectDexesInternal(cl, dexFiles, optimizedDir);
}
} catch (Throwable thr) {
throw new TinkerRuntimeException("Fail to create TinkerClassLoader.", thr);
}
}
@Keep
class CompoundEnumeration<E> implements Enumeration<E> {
private Enumeration<E>[] enums;
private int index = 0;
public CompoundEnumeration(Enumeration<E>[] enums) {
this.enums = enums;
}
@Override
public boolean hasMoreElements() {
while (index < enums.length) {
if (enums[index] != null && enums[index].hasMoreElements()) {
return true;
}View on GitHub (pinned to 1b7ea02c23)
Solutions
- Log and inspect the wrapped cause (Throwable thr) — NoSuchFieldException/NoSuchMethodException point to framework incompatibility, IOException to file issues.
- Confirm every ':'-separated dexPath segment exists, is a legal file (SharePatchFileUtil.isLegalFile) and is readable before constructing the loader.
- Upgrade tinker for per-version installer fixes; verify the failing device's Android version is supported.
- If cause is storage-related, clean the tinker directory (cleanPatch) so the patch re-applies cleanly next launch.
Example fix
// before
TinkerClassLoader tcl = new TinkerClassLoader(dexPath, optimizedDir, libraryPath, parent);
// after
for (String p : dexPath.split(":")) {
if (!p.isEmpty() && !SharePatchFileUtil.isLegalFile(new File(p))) {
throw new IllegalStateException("missing patch dex: " + p);
}
}
TinkerClassLoader tcl = new TinkerClassLoader(dexPath, optimizedDir, libraryPath, parent); Defensive patterns
Strategy: validation
Validate before calling
for (String p : dexPath.split(":")) {
if (!p.isEmpty() && !SharePatchFileUtil.isLegalFile(new File(p))) {
// refuse to construct loader with missing dex
}
} Try / catch
catch TinkerRuntimeException 'Fail to create TinkerClassLoader.' -> read the cause; reflection failures mean unsupported framework (disable patch), IO failures mean cleanPatch + retry
Prevention
- Validate every dex path segment is a legal file before constructing TinkerClassLoader.
- Keep tinker updated for OEM framework variations on V14/V19/V23 injection paths.
- Preserve the wrapped cause in crash reporting — the root throwable names the real failure.
When it happens
Trigger: injectDexesInternal throwing: reflection failures in V14/V19/V23 installers (field/method not found on the OEM framework ClassLoader), illegal dex files, IO errors reading dex/opt files, or odex-writing failures — anything thrown while merging dexElements.
Common situations: Older Android versions (V14/V19 path) with OEM-renamed framework internals; malformed dexPath entries; dex optimization failures writing to the optimized directory; storage permission loss between patch apply and load.
Related errors
- createInlineFence failed
- createDelegate failed
- getCurrentInstructionSet fail:
- Field {} not found in {}
- Method {} with parameters {} not found in {}
AI-assisted analysis of Tencent/tinker@1b7ea02c23 (2026-08-14).
Data as JSON: /api/errors/3a5838b65d944627.
Report an issue: GitHub.