/errors/java/unsupportedclassversionerror
java.lang.UnsupportedClassVersionError: compiled by a more recent version of the Java Runtime
- tool
- Java
- exit code
- 1
- versions
- Java 8 – 25
- os
- any
UnsupportedClassVersionError ... has been compiled by a more recent version of the Java Runtime (class file version 69.0), this version of the Java Runtime only recognizes class file versions up to 61.0 means the .class file targets a newer Java than the JVM running it. The two numbers identify the versions: class file 69 is Java 25, 61 is Java 17. Either run the program on Java 25 or newer, or recompile it with javac --release 17.
Reproduce it
Only a JDK 17 is needed: the class is compiled normally, then its major version field (bytes 6 and 7 of the class file) is set to 69, as if Java 25 had compiled it.
cat > Hello.java <<'EOF'
public class Hello { public static void main(String[] a) { System.out.println("hello"); } }
EOF
javac Hello.java
python -c "
d = bytearray(open('Hello.class','rb').read()); d[6:8] = (69).to_bytes(2,'big')
open('Hello.class','wb').write(d)"
java HelloOutput · exit 1
Error: LinkageError occurred while loading main class Hello java.lang.UnsupportedClassVersionError: Hello has been compiled by a more recent version of the Java Runtime (class file version 69.0), this version of the Java Runtime only recognizes class file versions up to 61.0
Class file versions
| Class file version | Java release |
|---|---|
| 52 | Java 8 |
| 55 | Java 11 |
| 61 | Java 17 |
| 65 | Java 21 |
| 69 | Java 25 |
Each release adds one: Java 9 is 53, Java 18 is 62, Java 24 is 68. To see what a class targets, use javap -v:
cat > Hello.java <<'EOF'
public class Hello { public static void main(String[] a) { System.out.println("hello"); } }
EOF
javac --release 11 Hello.java
javap -v Hello.class | grep major
java HelloOutput
major version: 55 hello
Fix: target the older runtime
javac --release 17 -d out src/*.java--release sets the class file version and also checks that the code only uses APIs of that release, which -source/-target alone do not. In Maven set <maven.compiler.release>17</maven.compiler.release>; in Gradle use java { toolchain { languageVersion = JavaLanguageVersion.of(17) } }.