Tencent/matrix · error · GradleException
process.errorStream.bufferedReader().readLines().joinTo(Stri…
Error message
process.errorStream.bufferedReader().readLines().joinTo(StringBuilder(), "\n").toString()
What it means
The V2 task runs Matrix-ApkChecker as an external Java process to analyze the APK; if ApkChecker exits non-zero, the task throws a GradleException whose message is the checker process's full stderr. The actual root cause is whatever ApkChecker printed — invalid checker arguments, JVM errors, or analysis failures.
Solutions
- Read the stderr text inside the exception — it is ApkChecker's own output; run the same ApkChecker command manually to reproduce.
- Verify `pathOfApkChecker` points at a runnable Matrix-ApkChecker jar (`java -jar apkchecker.jar`) and that `java` on PATH is a compatible JDK (8+).
- Fix the checker arguments/config the task generates (e.g. remove invalid mapping/resGuard file paths) so the checker exits 0.
- Give the checker more memory if it dies with OOM (set JAVA_OPTS or run ApkChecker standalone with -Xmx).
Example fix
// before: missing mapping file passed to checker mappingFile = "build/outputs/mapping/release/mapping.txt" // not generated (no minify) // after: only pass mapping when minifyEnabled mappingFile = (minifyEnabled ? "build/outputs/mapping/release/mapping.txt" : null)
Defensive patterns
Strategy: try-catch
Validate before calling
def exitCode = "java -jar ${pathOfApkChecker} --help".execute().waitFor()
assert exitCode == 0 : 'ApkChecker jar not runnable with current JDK' Try / catch
try { task.execute() } catch (GradleException e) { logger.error('ApkChecker failed: ' + e.message); throw e } Prevention
- Run ApkChecker standalone first to validate args/config.
- Ensure a compatible JDK (8+) is on PATH.
- Keep checker inputs (mapping/resGuard files) in sync with the actual build outputs.
When it happens
Trigger: ApkChecker process launched from `exec` finishes with `exitValue() != 0` — e.g. bad `-config` JSON for the checker, missing checker jar/classes, wrong JDK version, or the checker crashing on the APK.
Common situations: pathOfApkChecker pointing at a jar without a proper Main-Class manifest; ApkChecker run with an unsupported Java version; checker config file referencing resources that don't exist in the APK; out-of-memory in the checker JVM.
Understand the failure class
Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.
Related errors
- process.errorStream.bufferedReader().readLines().joinTo(Stri…
- the path of Matrix-ApkChecker $pathOfApkChecker is not…
- the path of Matrix-ApkChecker not found!
- This plugin must be applied after "com.android.library"…
- Debugging APK must be debuggable.
AI-assisted analysis of Tencent/matrix@3b8293bd65 (2026-09-08).
Data as JSON: /api/errors/8ae54db8ad821611.
Report an issue: GitHub.
Appendix: source
Thrown at matrix/matrix-android/matrix-gradle-plugin/src/main/kotlin/com/tencent/matrix/plugin/task/RemoveUnusedResourcesTaskV2.kt:438
val parametersOfIgnoredResources = StringBuilder()
if (configOfIgnoredResources.isNotEmpty()) {
for (ignore in configOfIgnoredResources) {
parametersOfIgnoredResources.append(ignore)
parametersOfIgnoredResources.append(',')
}
parametersOfIgnoredResources.deleteCharAt(parametersOfIgnoredResources.length - 1)
parameters.add("--ignoreResources")
parameters.add(parametersOfIgnoredResources.toString())
}
if (findOutDuplicates) {
parameters.add("-duplicatedFile")
}
val process = ProcessBuilder().command(parameters).start()
ApkUtil.waitForProcessOutput(process)
if (process.exitValue() != 0) {
throw GradleException(process.errorStream.bufferedReader().readLines()
.joinTo(StringBuilder(), "\n").toString())
}
val checkerOutputFile = File(pathOfBuildDir, "apk_checker.json") // -_-|||
if (checkerOutputFile.exists()) {
val jsonArray = Gson().fromJson(checkerOutputFile.readText(), JsonArray::class.java)
for (i in 0 until jsonArray.size()) {
if (jsonArray.get(i).asJsonObject.get("taskType").asInt == 12) {
val resList = jsonArray.get(i).asJsonObject.get("unused-resources").asJsonArray
for (j in 0 until resList.size()) {
resultOfUnused.add(resList.get(j).asString)
}
}
if (jsonArray.get(i).asJsonObject.get("taskType").asInt == 10) {
val duplicatedFiles = jsonArray.get(i).asJsonObject.get("files").asJsonArray
for (k in 0 until duplicatedFiles.size()) {
val obj = duplicatedFiles.get(k).asJsonObject
val md5 = obj.get("md5")View on GitHub (pinned to 3b8293bd65)