OpenJDK 9 for Fedora/EPEL

Looking to try out OpenJDK 9? If you didn’t know, OpenJDK 9 is going to be the reference implemtation for Java 9 (assuming the pattern for Java 7 and Java 8 continues). Pre-release packages for Fedora 23, 24, 25 and Rawhide as well as RHEL 7 are available on copr:

https://copr.fedoraproject.org/coprs/omajid/openjdk9/

Please note that these are not official Fedora (or RHEL) packages. Official Fedora packages will be proposed and added to Fedora closer to OpenJDK 9’s release.

To install on Fedora:

# dnf copr enable omajid/openjdk9
# dnf install java-9-openjdk-devel

To install on RHEL (or CentOS) 7:

$ wget https://copr.fedorainfracloud.org/coprs/omajid/openjdk9/repo/epel-7/omajid-openjdk9-epel-7.repo
$ su -
# cp omajid-openjdk9-epel-7.repo /etc/yum.repos.d/
# yum install java-9-openjdk-devel

Then use as follows:

$ /usr/lib/jvm/java-1.9.0-openjdk/bin/java -version

To make it the default Java version, use update-alternatives.

# update-alternatives --config java
# update-alternatives --config javac

If you are a user, making 9 the default may not be a great idea – OpenJDK 9 is in heavy development and lots of things are changing. There are also some known compatibility issues. On the other hand, if you are a Java developer, this will give you a good idea of how prepared your favourite libraries and tools are for Java 9.

IcedTea-Web and OpenJDK

I posted 3 patches today

The first patch is for OpenJDK 9. It creates a hole that allows alternative plugin implementations to plug into (pardon the pun)  OpenJDK and make use of existing plugin-specific classes in OpenJDK.

The second and third patches are for IcedTea-Web. They allow IcedTea-Web to (progressively) build against OpenJDK8 and OpenJDK9.

What does this mean? Soon we might actually be able to build and run IcedTea-Web against OpenJDK. Yes, an Open Source/Free Software plugin running on top of OpenJDK (without any custom patches). Of course, a lot of this is still up in the air. The OpenJDK folks might not accept the patch, though I am hopeful they will – it’s very small and conservative.

Fun times ahead!

SharedSecrets in OpenJDK

I have always been impressed by the effort OpenJDK folks go to maintain API compatibility. I recently came across a nifty little trick that is used in the OpenJDK codebase to help achieve this goal. Behold the SharedSecrets class! The name of the class is a little misleading since it doesn’t have anything to do with the cryptographic concepts of shared secrets. The javadocs do a (slightly) better job describing its purpose:

/** A repository of "shared secrets", which are a mechanism for
    calling implementation-private methods in another package without
    using reflection. A package-private class implements a public
    interface and provides the ability to call package-private methods
    within that package; the object implementing that interface is
    provided through a third package to which access is restricted.
    This framework avoids the primary disadvantage of using reflection
    for this purpose, namely the loss of compile-time checking. */

In other words, it is used to make private methods public, without using reflection! AND it works under a security manager! At first, I thought this was too good to be true but it turns out that the concept behind it is pretty simple. Here’s how it works. Suppose we have a class with a fixed public api and we wish to add a new method to it that we would like to be able to use internally within the project but not provide as an api:

public class FixedPublicApi {
  private static doFoo() { /* do something */ }
}

We could choose to add the doFoo method to another class (in fact, it will primarily be accessed through another class) and make it public, but let’s assume that the only way to avoid duplicating lots of code is to keep doFoo in FixedPublicApi. First we create an interface that exposes the method we want to be invoked:

public interface FooHandler {
  public void doFoo();
}

Then we modify the SharedSecrets class (or it’s equivalent in our codebase), to set the implementation for FooHandler

public class SharedSecrets {
  private static FooHandler fooHandler;
  public static void setFoo(FooHandler handler) {
    fooHandler = handler;
  }
  public static void foo() {
    fooHandler.doFoo();
  }
}

Finally we modify the FixedPublicApi class to install a handler:

public class FixedPublicApi {
  static {
     SharedSecrets.setFoo(new FooHandler() {
       public void doFoo() {
         FixedPublicApi.doFoo();
       }
     }
  }

  private static doFoo() { /* do something */ }
}

And that’s it! Now we can use SharedSecrets to call the private method:

  SharedSecrets.doFoo();

Hats off to whoever came up with this great technique.