java – Is it possible to compile Java 8 to run on Java 7 JVM?

The default methods require such changes to the bytecode and JVM that would have been impossible to run on Java 7. The Java 7 and earlier bytecode checker will reject interfaces with method bodies (except that static initialization method). Trying to emulate predefined methods with static methods on the calling side would not produce the same results, as predefined methods can be overridden in subclasses. Retrolambda it has limited support for default backport methods, but can never be fully backported because it really requires new JVM functionality.

Lambdas could run on Java 7 as is, if only the necessary API classes existed. The invokedynamic statement exists on Java 7, but it would have been possible to implement lambdas to generate the lambda classes at compile time (early JDK 8 builds did it that way) in which case it would have worked on any Java version. (Oracle decided to use invokedynamic for lambdas for future testing; maybe one day JVM will have first-class functions, so invokedynamic can be modified to use them instead of generating a class for each lambda, thus improving performance.) Retrolambda does that process all those statements invoked and replaces them with anonymous classes; the same as what Java 8 does at runtime when a dynamic lamdba call is called the first time.

Repeated annotations it’s just syntactic sugar. They are bytecode compatible with previous versions. In Java 7 you will only have to implement the helper methods yourself (eg. getAnnotationsByType ) that hide the implementation details of a container annotation that contains repeating annotations.

AFAIK, Type Annotations they only exist at compile time, so they shouldn’t require bytecode changes, so just change the bytecode version number of compiled Java 8 classes to make them work on Java 7.

Method parameter names exist in the bytecode with Java 7, so it is also compatible. It can be accessed by reading the bytecode of the method and looking at the names of the local variables in the debug information of the method. For example Spring Framework does exactly this to implement @ PathVariable , so there is probably a library method you could call. Since abstract interface methods do not have a method body, such debugging information does not exist for interface methods in Java 7 and AFAIK nor on Java 8.

The other new features they are mainly new APIs, HotSpot enhancements and tools. Some of the new APIs are available as third party libraries (e.g. ThreeTen-Backport And streamsupport ).

Summa summarum, the default methods require new JVM features but the other language features do not. If you want to use them, you will have to compile the code in Java 8 and then transform the bytecode with the format Retrolambda in Java 5/6/7. You need to change at least the version of the bytecode and javac does not allow -source 1.8 -target 1.7A retrotranslator is therefore required.

Leave a comment