iBotPeaches/Apktool · error · BrutException

Could not extract resource:

Error message

Could not extract resource: 

What it means

Thrown by brut.util.Jar when extracting a classpath resource to a temporary file fails. The inner cause is usually FileNotFoundException (resource not found: getResourceAsStream returned null) but any IOException during stream copy or temp-file creation is wrapped the same way. The message appends the resource name that failed.

Source

Thrown at brut.j.util/src/main/java/brut/util/Jar.java:68

    public static File extractToTmp(Class<?> clz, String name) throws BrutException {
        return extractToTmp(clz, name, "brut_util_Jar_");
    }

    public static File extractToTmp(Class<?> clz, String name, String tmpPrefix) throws BrutException {
        try (InputStream in = clz.getResourceAsStream(name)) {
            if (in == null) {
                throw new FileNotFoundException(name);
            }
            long suffix = ThreadLocalRandom.current().nextLong();
            suffix = suffix > Long.MIN_VALUE ? Math.abs(suffix) : 0;
            File fileOut = File.createTempFile(tmpPrefix, suffix + ".tmp");
            fileOut.deleteOnExit();

            BrutIO.copyAndClose(in, Files.newOutputStream(fileOut.toPath()));

            return fileOut;
        } catch (IOException ex) {
            throw new BrutException("Could not extract resource: " + name, ex);
        }
    }
}

View on GitHub (pinned to 79b63384d7)

Solutions

  1. Verify the resource exists on the same classloader the code uses: getClass().getClassLoader().getResourceAsStream(name) != null
  2. Fix the resource name — check exact case, package path, and whether a leading '/' is expected; print getClass().getProtectionDomain().getCodeSource() to confirm which jar is loaded
  3. If packaging a fat/shaded jar, ensure resource transform rules (maven-shade etc.) did not drop or relocate the resource
  4. Check the temp filesystem: df $TMPDIR / free disk, and -Djava.io.tmpdir override if the default is unwritable

Example fix

// before
File f = Jar.extract("/prebuilt/aapt"); // name wrong or resource missing

// after
String name = "/prebuilt/aapt";
if (Jar.class.getResourceAsStream(name) == null) {
    throw new IllegalStateException("Resource not on classpath: " + name);
}
File f = Jar.extract(name);
Defensive patterns

Strategy: validation

Validate before calling

String name = "/prebuilt/aapt";
boolean present = Jar.class.getClassLoader().getResourceAsStream(name) != null;
File f = present ? Jar.extract(name) : throwOrFallback();

Try / catch

try {
    File f = Jar.extract(name);
} catch (BrutException e) {
    if (e.getCause() instanceof FileNotFoundException) {
        // resource missing from classpath: packaging bug, fail loudly
        throw new IllegalStateException("bundled resource missing: " + name, e);
    }
    throw e; // IO error on copy/temp file: transient, may retry
}

Prevention

When it happens

Trigger: Jar.extract(...)/resource-lookup call where the named resource is absent from the classpath/jar (wrong name, leading slash mismatch, case difference), or where File.createTempFile / the copy stream fails (disk full, permissions on java.io.tmpdir).

Common situations: Bundled binaries (e.g. aapt, native helpers) missing from the shaded/fat jar; resources renamed between library versions; running from an IDE where resource dirs differ from the packaged jar; resource name built with a hardcoded '/' or wrong package prefix; read-only or full temp directory.

Related errors


AI-assisted analysis of iBotPeaches/Apktool@79b63384d7 (2026-08-14). Data as JSON: /api/errors/f8d6179b435c24f3. Report an issue: GitHub.