Tencent/matrix · error · RuntimeException

zipEntry is null when get from oldApk

Error message

zipEntry is null when get from oldApk

What it means

HprofBufferShrinker.addExtraInfo() rebuilds the shrunk APK by enumerating entries of the old APK's TinkerZipFile and copying each into the output. Although Enumeration.nextElement() is typed as possibly-null in this Tinker zip implementation, the library defensively throws RuntimeException if a null entry is ever produced, indicating a corrupted or unexpected zip structure.

Solutions

  1. Verify the input APK is a valid, complete zip (e.g. unzip -t oldApk) and re-obtain it if corrupted.
  2. Regenerate the shrunk file: delete shrinkResultFile and rerun the shrink pipeline to rule out a stale/partial output.
  3. Check free disk space and ensure the process writing the apk completed before HprofBufferShrinker reads it.
Defensive patterns

Strategy: try-catch

Validate before calling

File f = new File(shrinkResultPath);
if (!f.isFile() || f.length() == 0) {
    throw new IOException("old apk missing or empty: " + shrinkResultPath);
}

Try / catch

try {
    shrinker.addExtraInfo(...);
} catch (RuntimeException e) {
    Log.e(TAG, "old apk unreadable, regenerate", e);
}

Prevention

When it happens

Trigger: During addExtraInfo(), iterating zipFile.entries() of the shrinkResultFile (old APK) yields a null TinkerZipEntry from nextElement().

Common situations: Corrupted or partially written APK/zip file (interrupted download or build); an apk produced by a tool that emits entries the Tinker zip reader mis-parses; disk-full during prior shrink step leaving a truncated archive.

Understand the failure class

Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.

Related errors


AI-assisted analysis of Tencent/matrix@3b8293bd65 (2026-09-08). Data as JSON: /api/errors/6a111e3a6e69d1be. Report an issue: GitHub.

Appendix: source

Thrown at matrix/matrix-android/matrix-resource-canary/matrix-resource-canary-android/src/main/java/com/tencent/matrix/resource/hproflib/HprofBufferShrinker.java:110

            MatrixLog.e(TAG, "save property error:" + throwable);
            return false;
        } finally {
            MatrixUtil.closeQuietly(propertiesOutputStream);
        }

        TinkerZipOutputStream out = null;
        TinkerZipFile zipFile = null;
        try {

            out = new TinkerZipOutputStream(new BufferedOutputStream(new FileOutputStream(tempFile)));

            zipFile = new TinkerZipFile(shrinkResultFile);
            final Enumeration<? extends TinkerZipEntry> entries = zipFile.entries();

            while (entries.hasMoreElements()) {
                TinkerZipEntry zipEntry = entries.nextElement();
                if (zipEntry == null) {
                    throw new RuntimeException("zipEntry is null when get from oldApk");
                }
                String name = zipEntry.getName();
                if (name.contains("../")) {
                    continue;
                }
                TinkerZipUtil.extractTinkerEntry(zipFile, zipEntry, out);
            }
            Long crc = getCRC32(propertiesFile);
            if (crc == null) {
                MatrixLog.e(TAG, "new crc is null");
                return false;
            }
            TinkerZipEntry propertyEntry = new TinkerZipEntry(propertiesFile.getName());
            // add property file
            TinkerZipUtil.extractLargeModifyFile(propertyEntry, propertiesFile, crc, out);
        } catch (IOException e) {
            MatrixLog.e(TAG, "zip property error:" + e);
            return false;

View on GitHub (pinned to 3b8293bd65)