Java class and JAR viewer: which Java version does it need?
Got UnsupportedClassVersionError, or a jar you did not build? Drop the .jar or .class here. You get the Java version every class needs, the manifest with its Main-Class, the packages and classes, the Maven libraries bundled inside and who signed it. Each class shows its methods as Java signatures, its strings and its bytecode.
The file is read by this tab only. It is not uploaded and nothing in it is run.
What it shows
- The Java version it needs. Every class file records the version of the class format it was compiled to, in bytes 4 to 7. For a jar, every class is read and summed up, for example “All 37 classes outside META-INF/versions/ run on Java 8 or newer; META-INF/versions/9/ holds 1 class compiled for Java 9”. If a few classes need a newer Java than the rest, it names them. Those are the ones that throw
UnsupportedClassVersionErrorhalfway through a run. - The manifest. Main-Class (and whether that class is really in the jar), Automatic-Module-Name, Multi-Release, Class-Path, Created-By, the Implementation and OSGi Bundle versions, Spring Boot's Start-Class, and agent entries. The full
META-INF/MANIFEST.MFis one click away. - Libraries inside. Every
META-INF/maven/group/artifact/pom.propertiesasgroup:artifact:version. A “fat” or shaded jar carries one for each library copied into it, which is what you need when a security advisory names a library version. Jars nested inBOOT-INF/lib/orWEB-INF/lib/are listed too. - Who signed it. For a signed jar, the signer certificate from
META-INF/*.RSA,.DSAor.EC: name, issuer, validity dates and SHA-256 fingerprint, plus the digest algorithm in the.SFfile. - Every package and class. Pick one to see its access flags, superclass and interfaces, its fields and methods written as Java declarations (generic types included, from the Signature attribute), its annotations, and the text strings in its constant pool, searchable. Each method opens to a bytecode listing in the format of
javap -c.
What it cannot do
- No decompiling. You see signatures and bytecode, not the Java source. Decompilers such as CFR, Fernflower (in IntelliJ) and Procyon rebuild something close to the source; they run on your own computer.
- Nothing runs. The page reads bytes and never loads or executes a class. It cannot say what the program does when it runs, and it is not a malware scan.
- Obfuscated names stay obfuscated. A class that ProGuard renamed to
a.b.cis shown asa.b.c. Only the build's mapping file can reverse that. - Signatures are not verified. The signer certificate is read and fingerprinted, but the digests are not checked against the classes.
jarsigner -verifydoes that. - Android code is different. An .apk holds Dalvik bytecode (
classes.dex), not class files. The APK viewer reads those apps.
Class file versions and Java releases
The number after “class file version” in a Java error is the major version of the class. Since Java 5 the rule is simple: Java N writes major version 44 + N. A JVM runs every class up to its own number and refuses anything newer.
| Major version | Java release | Major version | Java release |
|---|---|---|---|
| 45 | JDK 1.0.2 and 1.1 (minor 3) | 58 | Java 14 |
| 46 | Java 1.2 | 59 | Java 15 |
| 47 | Java 1.3 | 60 | Java 16 |
| 48 | Java 1.4 | 61 | Java 17 (LTS) |
| 49 | Java 5 | 62 | Java 18 |
| 50 | Java 6 | 63 | Java 19 |
| 51 | Java 7 | 64 | Java 20 |
| 52 | Java 8 (LTS) | 65 | Java 21 (LTS) |
| 53 | Java 9 | 66 | Java 22 |
| 54 | Java 10 | 67 | Java 23 |
| 55 | Java 11 (LTS) | 68 | Java 24 |
| 56 | Java 12 | 69 | Java 25 (LTS) |
| 57 | Java 13 | 70 | Java 26 |
Useful to know
- Reading the error
UnsupportedClassVersionError: com/example/App has been compiled by a more recent version of the Java Runtime (class file version 61.0), this version of the Java Runtime only recognizes class file versions up to 52.0means App needs Java 17 (61) and thejavathat ran it is Java 8 (52). Either run it with Java 17 or newer (check withjava -version; an IDE or build tool may use a different Java than your terminal), or rebuild the code withjavac --release 8(Maven:<maven.compiler.release>8</maven.compiler.release>).- Build-Jdk-Spec is not the version you need
- The manifest's
Build-Jdk-SpecorCreated-Bysays which Java ran the build, not which Java the classes target. Apache Commons CLI 1.9.0 is an example: its manifest saysBuild-Jdk-Spec: 17, but its classes are version 52 and run on Java 8. Only the class files tell you the version they need. - Multi-release jars
- Since Java 9, a jar whose manifest says
Multi-Release: truecan carry extra copies of classes underMETA-INF/versions/N/, which Java N and newer load instead of the base ones. Older Javas ignore that folder, so the base classes set the minimum. Many libraries put just amodule-info.classinMETA-INF/versions/9/to become a named module while still running on Java 8. - Preview features
- A class compiled with
--enable-previewhas minor version 65535. It runs only on exactly the Java release that compiled it, started with--enable-preview, and the page says so. - Constant pool strings
- Every text literal in a class's code (messages, SQL, URLs, property names, sometimes a hard-coded password) is stored as plain text in its constant pool. Searching the strings is the quickest way to see what a class talks to without decompiling it.