Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Enhance library for Java 8 while keeping backwards compatibility

I'm developing an open source library in Java and would like to ensure that it is convenient for Java 8 users, and takes advantage of new concepts in Java 8 wherever possible (lambdas etc.)

At the same time I absolutely need to maintain backwards compatibility (the library must still be usable for people using Java 6 or 7).

What useful features from Java 8 can I adopt that would be beneficial for library users without breaking library compatibility for users of older Java versions?

like image 886
mikera Avatar asked Apr 20 '14 12:04

mikera


People also ask

Is JDK 8 backwards compatible?

Backward Compatibility Java versions are expected to be binary backwards-compatible. For example, JDK 8 can run code compiled by JDK 7 or JDK 6. It is common to see applications leverage this backwards compatibility by using components built by different Java version.

Is Java 11 fully backward compatible with Java 8?

Java 11 is backwards compatible with Java 8. So you can swiftly change from Java 8 to 11.

Can a Java 8 project use Java 11 library?

The class files created by Java 8 are still executable in Java 11; however, there have been other changes in the Java runtime (library changes, etc.) that might require modification of the code. These modifications may be made in Java 8 and compiled with Java 8 making it compatible with the Java 11 runtime.

Are JDK versions backwards compatible?

The JDK compiler is not backward compatible. So code cannot be compiled by java 1.5 to run on 1.4. 2 for example. Save this answer.


2 Answers

I don't know about your library, this advice might be slightly off.

Lambdas: Don't worry. Any functional interface can be implemented using a Lambda expression.

Method references: Same as lambdas, they should just be usable.

Streams: If this fits your library, you should use them, but keeping compatibility is harder here. The backwards compatibility could be achieved using a second library part, wrapping around the base library and hooking into the public API of it. It could therefore provide additional sugar/functionality without abandoning Java 6/7.

Default methods: By all means, use these! They are a quick/cheap/good way to enhance existing implementations without breaking them. All default methods you add will be automatically available for implementing classes. These will, however, also need the second library part, so you should provide the base interfaces in your base library, and extend the interfaces from the companion-library.

Don't fork the library, abandoning the old one, as there are still many developers who cannot use Java 8, or even Java 7. If your library is sensible to use on e.g. Android, please keep that compatibility.

like image 105
tilpner Avatar answered Oct 14 '22 16:10

tilpner


If you want your code to be usable by Java 6 consuming VMs, you have to write using Java 6 language compatibility. Alas. The bytecode format critically changed from 6 to 7, so code for 7 and 8 won't load into 6. (I found this with my own code migrating to 7; even when all I was using was multi-catch — which should be writable in the 6 bytecode — I couldn't build it for a 6 target. The compiler refused.)

I've yet to experiment with 8, but you'll have to be careful because if you depend on any new Java packages or classes, you will still be unable to work with older versions; the old consuming VMs simply won't have access to the relevant classes and won't be able to load the code. In particular, lambdas definitely won't work.

Well, can we target a different classfile version? There's no combination of source and target that will actually make javac happy with this.

kevin$ $JAVA8/bin/javac -source 1.8 -target 1.7 *.java
javac: source release 1.8 requires target release 1.8

So there's simply no way to compile Java source with lambdas into a pre-Java 8 classfile version.

My general take is that if you want to support old versions of Java, you have to use old versions of Java to do so. You can use a Java 8 toolchain, but you need Java 7 or Java 6 source. You can do it by forking the code, maintaining versions for all the versions of Java you want to support, but that's far more work than you could ever justify as a lone developer. Pick the minimum version and go with that (and kiss those juicy new features goodbye for now, alas).

like image 45
Donal Fellows Avatar answered Oct 14 '22 17:10

Donal Fellows