Has anybody yet backported Lambda Expressions to Java 7?
Asked Answered
A

1

45

Reading about what kind of bytecode Java 8 produces from lambdas, it came to my mind the time when Java 5 was released. Back then there was Retroweaver and other tools for converting bytecode compiled with JDK 5 to run on JRE 1.4.

Has anybody yet created such a backporting tool for Java 8 lambdas? It would let Java developers start using lambdas already today on production-quality Java 7 JREs, without having to wait 6-12 months for Java 8's GA release.

Here is my analysis of why such as backporter should be implementable relatively easily:

Java 8 lambdas don't seem to use any JVM features that Java 7 wouldn't have (e.g. invokedynamic), and the java.lang.invoke.LambdaMetafactory class and its dependencies look like pure Java, so it should be possible to implement them in a 3rd-party library. Thus bytecode compiled with JDK 8 could be made to run on JRE 7 by adding a 3rd-party library with a copy of LambdaMetafactory (under a different package) and by transforming the bytecode to use that metafactory instead. Maybe also generate some synthetic classes and methods to bypass accessibility checks, as java.lang.invoke.MagicLambdaImpl seems to imply. Or then generate anonymous inner classes for all lambdas, like some of the first lambda-enabled Early Access JDKs did.

Ardenardency answered 19/7, 2013 at 22:41 Comment(3)
In case nobody reports such a thing soon, I might write one. Here is the (currently empty) github repository: github.com/orfjackal/retrolambdaArdenardency
Hmmm... this would meet a real demand. If you can get it to work correctly and with as few limitations as possible, I think it's a winner.Indene
I experimented a bit on my own and found out that with bytecode transformation it is even possible to run the classes compiled for Java 8 directly with a Java 7 JVM with an appropriate javaagent. The JVM will accept the classes even when they have an unsupported format as long as the instrumentation via registered class file tranformers results in a known, valid format. I did not implement all features (yet) but I think it’s a promising approach as keeping the deployed classes unmodified means they might still benefit from future Java 8 versions.Bathulda
A
44

There is now Retrolambda for converting Java 8 bytecode, which uses lambda expressions and method references, to work on Java 7, 6 or 5. (Java 1.4 gave verify errors; did not investigate further.)

Ardenardency answered 23/7, 2013 at 10:34 Comment(8)
AFAIK, nobody has yet tried it on Dalvik, though the wish has been mentioned a couple of times. Do you want to be the first one to test it and write a blog post? ;)Ardenardency
I hear it works on Dalvik. See this comment.Ardenardency
Very, very, very dangerous! This compiles code against the Java 8 APIs, which may be different or not exist on Java 7. You'll never know until runtime. I strongly recommend you avoid this! A slightly different (but safe) approach would be to use xtend, which compiles to Java 7 source.Coccidioidomycosis
@ScottStanchfield That's why all tests (from unit to end-to-end tests) need to be run under Java 7 or whatever is the target platform, as said in Retrolambda's documentation: github.com/orfjackal/retrolambda#tips Here's how to do it - just a single line of configuration: github.com/orfjackal/jumi/blob/…Ardenardency
The key being "all tests" - you absolutely must have all Java runtime calls covered by unit tests to double check. That amount of coverage is only feasible in the most trivial applications. This is a very bad idea.Coccidioidomycosis
You should anyways fully test your programs. Your point is moot.Ardenardency
Also, it would be straightforward to write a program that goes through all instructions in a program to check that the APIs they use exist, if you are not properly testing your programs.Ardenardency
@rekire another person has made a Gradle plugin for it: github.com/evant/gradle-retrolambdaArdenardency

© 2022 - 2024 — McMap. All rights reserved.