Published 26 Oct, 2022

Java - Is java byte-code always forward compatible?

Category Java
Modified : Nov 30, 2022

I understand that the byte code generated by version JDK X is guaranteed to work on JVM Y, provided Y >= X.

Does this hold good for all versions of JDK/JVM? i.e Is it fair to expect class files generated by JDK 1 to work on JVM 11?

Referred to JVM specs, JDK 8 compatibility guide and Java 11 JSR Could not find a precise answer there.


There are 2 suggested solutions here and each one has been listed below with a detailed description. The following topics have been covered briefly such as Java, Jvm, Compatibility, Jvm Bytecode. These have been categorized in sections for a clear and precise explanation.


The bytecode itself should work in future versions. Until now this holds true but nobody knows if this will be true for all future.

What changes, and can break your program, are changes in the API. Deprecated APIs may vanish in the future and then your program will not work anymore and may throw a java.lang.NoSuchMethodError when referencing such a method.


Java byte code is not forward compatible, JVMs are backward compatible. The difference between these properties is, that any future JVM may decide to drop backward compatibility to a certain older byte code version.

Java byte code has been designed in a way that such cut is rarely needed, but there has been a deliberate limitation of backward compatibility already. Starting with Java 8, the support for different semantics of invokespecial of Java 1.0 has been dropped. As JVM Spec §4.1 states:

The ACC_SUPER flag indicates which of two alternative semantics is to be expressed by the invokespecial instruction (§invokespecial) if it appears in this class or interface. Compilers to the instruction set of the Java Virtual Machine should set the ACC_SUPER flag. In Java SE 8 and above, the Java Virtual Machine considers the ACC_SUPER flag to be set in every class file, regardless of the actual value of the flag in the class file and the version of the class file.

The ACC_SUPER flag exists for backward compatibility with code compiled by older compilers for the Java programming language. In JDK releases prior to 1.0.2, the compiler generated access_flags in which the flag now representing ACC_SUPER had no assigned meaning, and Oracle's Java Virtual Machine implementation ignored the flag if it was set.

This does not imply that early Java 1.0 code doesn’t work in general. Only code relying on the outdated and now unsupported semantics of invokespecial of that early version will break.

Another change is that the instructions jsr and ret have been removed¹, however, this change has been tied to newer class file versions, so these instructions are still supported for older class file versions, so it doesn’t break existing code. But this could be a reason for future JVMs do drop the support for these older versions.

¹ JVM spec §4.9.1:

If the class file version number is 51.0 or above, then neither the jsr opcode or the jsr_w opcode may appear in the code array.

The ret instruction has not been mentioned, but doesn’t work without jsr instructions.