Tencent/tinker · error · IllegalArgumentException

Bad method: ${value}

Error message

Bad method: ${value}

What it means

setMethod only accepts the two compression methods the zip writer supports: STORED (0, no compression) and DEFLATED (8, default). Any other int — including values that exist in the zip spec but are not implemented here (e.g. BZIP2 12, LZMA 14) or -1 sentinels from other APIs — throws IllegalArgumentException('Bad method'). The guard fires before any state changes, so the entry keeps its previous method.

Source

Thrown at third-party/tinker-ziputils/src/main/java/com/tencent/tinker/ziputils/ziputil/TinkerZipEntry.java:314

     *         or -1 if the compression method has not been set.
     */
    public int getMethod() {
        return compressionMethod;
    }

    /**
     * Sets the compression method for this entry to either {@code DEFLATED} or {@code STORED}.
     * The default is {@code DEFLATED}, which will cause the size, compressed size, and CRC to be
     * set automatically, and the entry's data to be compressed. If you switch to {@code STORED}
     * note that you'll have to set the size (or compressed size; they must be the same, but it's
     * okay to only set one) and CRC yourself because they must appear <i>before</i> the user data
     * in the resulting zip file. See {@link #setSize} and {@link #setCrc}.
     * @throws IllegalArgumentException
     *             when value is not {@code DEFLATED} or {@code STORED}.
     */
    public void setMethod(int value) {
        if (value != STORED && value != DEFLATED) {
            throw new IllegalArgumentException("Bad method: " + value);
        }
        compressionMethod = value;
    }

    /**
     * Gets the name of this {@code ZipEntry}.
     *
     * <p><em>Security note:</em> Entry names can represent relative paths. {@code foo/../bar} or
     * {@code ../bar/baz}, for example. If the entry name is being used to construct a filename
     * or as a path component, it must be validated or sanitized to ensure that files are not
     * written outside of the intended destination directory.
     *
     * @return the entry name.
     */
    public String getName() {
        return name;
    }

View on GitHub (pinned to 1b7ea02c23)

Solutions

  1. Normalize the method explicitly: entry.setMethod(TinkerZipEntry.DEFLATED) (or STORED) instead of forwarding a foreign constant.
  2. When importing entries from another archive, whitelist STORED/DEFLATED and either decompress-and-rewrite or skip unsupported entries.
  3. If you meant 'not yet set', do not call setMethod at all — DEFLATED is the default.

Example fix

// before
entry.setMethod(sourceEntry.getMethod()); // may be e.g. 14 (LZMA)

// after
int m = sourceEntry.getMethod();
entry.setMethod(m == TinkerZipEntry.STORED ? TinkerZipEntry.STORED : TinkerZipEntry.DEFLATED);
Defensive patterns

Strategy: validation

Validate before calling

static boolean supportedMethod(int m) {
    return m == TinkerZipEntry.STORED || m == TinkerZipEntry.DEFLATED;
}

int m = sourceEntry.getMethod();
if (!supportedMethod(m)) {
    m = TinkerZipEntry.DEFLATED; // or skip the entry
}
entry.setMethod(m);

Prevention

When it happens

Trigger: Calling setMethod(value) with value != TinkerZipEntry.STORED && value != TinkerZipEntry.DEFLATED; passing a method constant from another zip library or a raw central-directory method field for an unsupported algorithm.

Common situations: Copying entries verbatim from archives produced by tools that used LZMA/BZIP2/PPMd; mapping java.util.zip constants through a custom int; passing -1 ('not set') read from a partially populated entry.

Related errors


AI-assisted analysis of Tencent/tinker@1b7ea02c23 (2026-08-14). Data as JSON: /api/errors/c8b323ca62f8f6af. Report an issue: GitHub.