pxb1988/dex2jar · error · DexException

Odex unsupported.

Error message

Odex unsupported.

What it means

DexFileReader validates the 4-byte magic at the start of the container. A 'dey ' magic means an odex (optimized/odexed) file, which dex2jar does not parse; it throws DexException('Odex unsupported.'). An odex contains a DVM-specific pre-optimized format rather than a portable DEX.

Solutions

  1. Obtain the portable classes.dex instead — extract from the APK, or deopt/deodex the odex (e.g. with an oat/dex deoptimizer tool matching the device's Android version)
  2. Check the file magic before parsing: read the first 4 bytes and only pass 'dex\n' files to DexFileReader
  3. Catch DexException around DexFileReader open/accept to classify the input cleanly

Example fix

// before
new DexFileReader(odexFile);
// after
byte[] magic = readFirstBytes(odexFile, 4);
if (!Arrays.equals(magic, new byte[]{'d','e','y','\n'})) {
    new DexFileReader(odexFile); // proceed only for real dex
} else {
    throw new IllegalArgumentException("deodex the file first: " + odexFile);
}
Defensive patterns

Strategy: validation

Validate before calling

static boolean isPortableDex(Path p) throws IOException {
    byte[] m = new byte[4];
    try (InputStream in = Files.newInputStream(p)) {
        if (in.read(m) != 4) return false;
    }
    return m[0]=='d' && m[1]=='e' && m[2]=='x' && m[3]=='\n';
}

Try / catch

try {
    DexFileReader reader = new DexFileReader(file);
} catch (DexException e) {
    if (e.getMessage().contains("Odex")) {
        throw new IllegalStateException("deodex required: " + file, e);
    }
    throw e;
}

Prevention

When it happens

Trigger: Opening an .odex file (or any stream whose first bytes are 'dey\n') with DexFileReader or higher-level APIs that delegate to it.

Common situations: Trying to decompile system-app odex files pulled from a device /system partition; passing a yanked odex instead of its corresponding dex; old baksmali-style workflows.

Related errors


AI-assisted analysis of pxb1988/dex2jar@b5bda4fb49 (2026-09-08). Data as JSON: /api/errors/525aa16dcfdb3de7. Report an issue: GitHub.

Appendix: source

Thrown at dex-reader/src/main/java/com/googlecode/d2j/reader/DexFileReader.java:162

    final int dex_version;

    /**
     * read dex from a {@link ByteBuffer}.
     * 
     * @param in
     */
    public DexFileReader(ByteBuffer in) {
        in.position(0);
        in = in.asReadOnlyBuffer().order(ByteOrder.BIG_ENDIAN);
        int magic = in.getInt() & 0xFFFFFF00;

        final int MAGIC_DEX = 0x6465780A & 0xFFFFFF00;// hex for 'dex ', ignore the 0A
        final int MAGIC_ODEX = 0x6465790A & 0xFFFFFF00;// hex for 'dey ', ignore the 0A

        if (magic == MAGIC_DEX) {
            // ok
        } else if (magic == MAGIC_ODEX) {
            throw new DexException("Odex unsupported.");
        } else {
            throw new DexException("Magic unsupported.");
        }
        int version = in.getInt() >> 8;
        if (version < DEX_035 || version > DEX_040) {
            System.err.println("Unknown DEX version. Trying anyway...");
        }
        this.dex_version = version;
        in.order(ByteOrder.LITTLE_ENDIAN);

        // skip uint checksum
        // and 20 bytes signature
        // and uint file_size
        // and uint header_size 0x70
        skip(in, 4 + 20 + 4 + 4);

        int endian_tag = in.getInt();
        if (endian_tag != ENDIAN_CONSTANT) {

View on GitHub (pinned to b5bda4fb49)