AlternativeImplementation

From APIDesign

Revision as of 05:46, 16 February 2021 by JaroslavTulach (Talk | contribs)
(diff) ←Older revision | Current revision (diff) | Newer revision→ (diff)
Jump to: navigation, search

Do you want to run your application on JDK8, but use JDK11 APIs? That's traditionally done with a reflection. Use JDK8 APIs directly and let javac compile your code against them. Whenever using JDK11 APIs, resort to reflection and call them in such a verbose, unsafe manner. That's indeed possible, but especially with modularity one has better option. Create few modules/JARs and let them work in smooth orchestration.

The Integration point API

When you need to access a functionality which requires different code to run on JDK8 and JDK11, start by defining an APISeam:

interface BetterHandler {
  void handleInBetterWay();
}

and in your code locate it via ServiceLoader or Lookup library and use it:

BetterHandler h = ServiceLoader().load(BetterHandler.class);
if (h == null) {
  // JDK8 default behavior
} else {
  h.handleInBetterWay();
}

Compile these pieces of code to run on JDK8. Btw. that can easily be done with JDK11 javac - just use the --release 8 - flag. Then the javac is only going to expose JDK8 API for you - e.g. the resulting JAR is going to run on JDK8.

Now let's compile the JDK11 part of the application:

@ServiceProvider(service=BetterHandler.class)
public class JDK11EnhancedHandler implements BetterHandler {
  public void handleInBetterWay() {
      // directly use JDK11 APIs  
  }
}

ServiceProvider is a comfortable way to generate META-INF/services/BetterHandler registration without risk of making typos. One can of course, create the ServiceLoader registration manually.

Personal tools
buy