shwenzhang/AndResGuard · error · RuntimeException
Failed to read resource
Error message
Failed to read <page> resource
What it means
printUsage reads a usage/help page from the classpath via getResourceAsStream and prints it. When reading the stream throws an IOException, it is rethrown as a RuntimeException "Failed to read <page> resource". This means the tool could not read its own bundled help text, typically because the resource is missing from the packaged jar or the stream failed mid-read.
Solutions
- Use the intact AndResGuard/apksigner build artifact so the usage text resources (e.g. /apksigner/help/*.txt) are on the classpath.
- If running from an IDE or fat jar, add a resources-inclusion rule (keep the help resource files) to the build config.
- Report/patch printUsage to handle a null stream explicitly instead of relying on IOException.
- As a workaround, consult apksigner usage documentation offline instead of triggering the help page.
Example fix
// before
} catch (IOException e) {
throw new RuntimeException("Failed to read " + page + " resource");
}
// after
} catch (IOException | NullPointerException e) {
throw new RuntimeException("Failed to read " + page + " resource - resource missing on classpath", e);
} Defensive patterns
Strategy: try-catch
Validate before calling
java
URL url = ApkSignerTool.class.getResource(page);
if (url == null) {
throw new IllegalStateException("Usage page resource missing from classpath: " + page);
} Try / catch
java
try {
printUsage(page);
} catch (RuntimeException e) {
if (e.getMessage() != null && e.getMessage().startsWith("Failed to read")) {
System.err.println("Help resources missing; see online docs instead.");
} else {
throw e;
}
} Prevention
- Keep the apksigner help resource files in the packaged jar (check build resource-exclusion rules).
- Verify jar contents with `unzip -l apksigner.jar | grep help` before distributing.
- When shading/proguarding, add keep rules for resource files.
When it happens
Trigger: Running main/sign/verify which calls printUsage("/apksigner/help/...") when usage output is required, and the classpath resource referenced by `page` is absent (getResourceAsStream returns null, causing NPE/IOException on read) or the underlying stream throws IOException while reading.
Common situations: Running a repackaged/proguarded jar where the help text resources were stripped; invoking apksigner classes from a classpath that excludes the resource directory; corrupted or partially extracted build artifact.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- No keystore passwords
- No key passwords
- No passwords
- Unsupported command: . See --help for supported commands
- Unsupported option: . See --help for supported options.
AI-assisted analysis of shwenzhang/AndResGuard@e4df245d82 (2026-09-12).
Data as JSON: /api/errors/09f013d4e18ce908.
Report an issue: GitHub.
Appendix: source
Thrown at AndResGuard-core/src/main/java/apksigner/ApkSignerTool.java:495
return;
}
if ((warningsTreatedAsErrors) && (warningsEncountered)) {
System.exit(1);
return;
}
}
private static void printUsage(String page) {
try (BufferedReader in = new BufferedReader(new InputStreamReader(
ApkSignerTool.class.getResourceAsStream(page),
StandardCharsets.UTF_8
))) {
String line;
while ((line = in.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
throw new RuntimeException("Failed to read " + page + " resource");
}
}
private static byte[] readFully(File file) throws IOException {
ByteArrayOutputStream result = new ByteArrayOutputStream();
try (FileInputStream in = new FileInputStream(file)) {
drain(in, result);
}
return result.toByteArray();
}
private static void drain(InputStream in, OutputStream out) throws IOException {
byte[] buf = new byte[65536];
int chunkSize;
while ((chunkSize = in.read(buf)) != -1) {
out.write(buf, 0, chunkSize);
}
}View on GitHub (pinned to e4df245d82)