Konloch/bytecode-viewer · error · ClassFileFormatException

Invalid Java .class file

Error message

Invalid Java .class file

What it means

ExtractDirectoryPath reads the first 4 bytes of the given file and compares them to the Java class-file magic number 0xCAFEBABE. If they differ, it throws ClassFileFormatException('Invalid Java .class file'), signaling the path does not point to a real JVM class file. This is a guard so jd-gui glue code never parses a non-class resource as bytecode.

Source

Thrown at src/main/java/the/bytecode/club/bytecodeviewer/decompilers/jdgui/JDGUIClassFileUtil.java:50

    public static final char INTERNAL_PACKAGE_SEPARATOR = '/';
    public static final String CLASS_FILE_SUFFIX = ".class";

    /*
     * Lecture rapide de la structure de la classe et extraction du nom du
     * repoertoire de base.
     */
    public static String ExtractDirectoryPath(String pathToClass)
    {
        String directoryPath;

        try (FileInputStream fis = new FileInputStream(pathToClass);
             BufferedInputStream bis = new BufferedInputStream(fis);
             DataInputStream dis = new DataInputStream(bis))
        {
            int magic = dis.readInt();
            if (magic != ClassFileReader.JAVA_MAGIC_NUMBER)
            {
                throw new ClassFileFormatException("Invalid Java .class file");
            }

            /* int minor_version = */
            dis.readUnsignedShort();
            /* int major_version = */
            dis.readUnsignedShort();

            Constant[] constants = DeserializeConstants(dis);

            /* int access_flags = */
            dis.readUnsignedShort();
            int this_class = dis.readUnsignedShort();

            if (this_class > constants.length)
            {
                throw new ClassFileFormatException("Unknown Java structure");
            }
            Constant c = constants[this_class];

View on GitHub (pinned to 31430e0033)

Solutions

  1. Check the file starts with bytes CA FE BA BE before calling: read the first 4 bytes yourself and skip non-class files.
  2. Ensure you pass only compiled .class files (e.g. from bin/build output), not sources, JARs, or resources.
  3. If the file should be a class but is corrupt, recompile or re-extract it from the original JAR/APK.
  4. If the file is a JAR, extract it first and pass the individual .class entries.
  5. Handle ClassFileFormatException per-file and skip the file instead of letting it abort a batch scan.

Example fix

// before
String dir = JDGUIClassFileUtil.ExtractDirectoryPath(somePath);

// after
try (FileInputStream in = new FileInputStream(somePath)) {
    int magic = (in.read() << 24) | (in.read() << 16) | (in.read() << 8) | in.read();
    if (magic != 0xCAFEBABE) return; // not a class file, skip
}
String dir = JDGUIClassFileUtil.ExtractDirectoryPath(somePath);
Defensive patterns

Strategy: validation

Validate before calling

static boolean looksLikeClassFile(String path) throws IOException {
    try (FileInputStream in = new FileInputStream(path)) {
        return in.read() == 0xCA && in.read() == 0xFE && in.read() == 0xBA && in.read() == 0xBE;
    }
}

Type guard

static boolean isJavaClassMagic(byte[] first4) {
    return first4 != null && first4.length >= 4
        && first4[0] == (byte)0xCA && first4[1] == (byte)0xFE
        && first4[2] == (byte)0xBA && first4[3] == (byte)0xBE;
}

Try / catch

try {
    String dir = JDGUIClassFileUtil.ExtractDirectoryPath(path);
} catch (org.jd.core.v1.service.deserializer.classfile.ClassFileFormatException e) {
    logger.warn("Not a valid class file: {}", path);
}

Prevention

When it happens

Trigger: Calling JDGUIClassFileUtil.ExtractDirectoryPath(pathToClass) on a file whose first 4 bytes are not 0xCAFEBABE — e.g. a .java source file, a JAR/ZIP, a text resource, an HTML error page saved with a .class name, a truncated or corrupt file, or a Dex file.

Common situations: Globbing a directory and feeding every file (resources, META-INF, .java) to ExtractDirectoryPath instead of only .class files; an unpacked APK where resources were mislabeled; a corrupted download; pointing at the source folder rather than the compiled output.

Related errors


AI-assisted analysis of Konloch/bytecode-viewer@31430e0033 (2026-09-05). Data as JSON: /api/errors/5de27925ae314f91. Report an issue: GitHub.