Multi-Release jars intended use cases

James Roper james at
Mon Mar 26 01:58:47 UTC 2018

Hi all,

According to Alan Bateman, MR jars can be used to introduce JDK9 API
features on classes, such that javac can compile code against them to use
the JDK9 specific API provided by the JDK9 version of the class, and still
have the same classes be compatible with (and loadable by) JDK8:

My question is whether this is a recommended practice or not. Let me put
forward a practical example of a place where we might want to use this.

The 4 Reactive Streams interfaces (Publisher, Subscriber, Processor and
Subscription) were first available in the org.reactivestreams project,
under the package name org.reactivestreams. They were then added to JDK9,
as inner interfaces of java.util.concurrent.Flow. Would it be considered a
good use of MR jars to make the org.reactivestreams interfaces extend their
juc.Flow counterparts when running and compiling by JDK9+? So, for example,
in JDK8 and earlier you get:

package org.reactivestreams;

public interface Publisher<T> {
  void subscribe(Subscriber<? super T> s);

While on JDK9, using the MR feature, you get this:

package org.reactivestreams;

import java.util.concurrent.Flow;

public interface Publisher<T> extends Flow.Publisher<T> {
  void subscribe(Subscriber<? super T> s);
  default void subscribe(Flow.Subscriber<? extends T> s) {
    if (s instanceof Subscriber) {
      this.subscribe((Subscriber) s);
    } else {
      this.subscribe(new FlowSubscriberAdapter<>(s));

The advantage of this approach is that it means if you have a library that
produces org.reactivestreams.Publisher, then without any changes to that
library to support JDK9, you can pass it to another library (eg, the JDK9
HTTP client) that accepts Flow.Publisher. Of course, it's not a panacea to
solving the migration problem of org.reactivestreams to juc.Flow, but it
goes a long way to helping.

But of course, while the JDK *does* support this, that doesn't necessarily
mean that we *should* use it that way, especially if it wasn't intended to
be used in that way. Tooling, such as IDEs and compilers for other JVM
languages, probably won't support this out of the box and may still need to
catch up, and if it was never intended to be used in that way in the first
place, then the tooling may decide not to implement it to work in that way.

So it would be nice to have an official statement about whether the above
use case is using the MR feature as intended, and whether that use case is
considered a good practice or not.



*James Roper*
*Senior Octonaut*

Lightbend <> – Build reactive apps!
Twitter: @jroper <>

More information about the core-libs-dev mailing list