About an old post

It is a bit strange when an old rant of mine keeps beeing popular in search results and server stats. That’s why I updated an old post with a disclaimer. I don’t want to keep spreading bad air that is long resolved.

Advertisements

Awesome stuff

1. Christian ‘Twisti’ Thalinger joins the HotSpot team. Congratulations!
2. Neil Young did a hilarious video:

It’s so bad, it really stinks. And that makes it awesome.
3. Cacio now supports heavyweight windows with decorations. Yes, they are implemented using Swing, it’s using JRootPane, which will also enable to implement AWT menus. It’s a bit magical:
Caciocavallo heavyweight windows w/ decorations

Even SwingSet3 works, with all the fluffy effects on DirectFB:

SwingSet3 on DirectFB

Friends for Java

Often (while working on OpenJDK’s code for example) I come across code where a class in one package needs to access private or package private stuff in another package, but that stuff can’t be made public. For example, an implementation class sometimes needs access to some API class, but we don’t want to open up the API class generally. Also, the implementation stuff cannot easily be moved to the API package.

The first instinct seems to be to use reflection to solve that problem. I’ve also seen some cases where JNI is used to access private stuff (/me eyes to the Java2D and AWT teams..). However, these approaches have their own disadvantages:

  • Not compile-time safe. If the accessed method changes, the compiler won’t block you. You also get no type checking.
  • You have to be careful about security manager issues, if your code needs to run w/ security manager.
  • Performance could be worse, depending on the VM.

Other languages (like C++) have the friend keyword, which allows to explicitly grant access to private code to another class or function (the friend). This can be quite useful, and I want to show how to do something similar in Java (also inspired by some code in OpenJDK btw).

Let’s assume the following classes:

package api;
public class A {
  void doSecretSauce() {
    // Doing secret sauce here.
  }
}
package impl;
public class B {
  void needsSecretSauce() {
    // TODO: How to do secret sauce here??
  }
}

Now, how can needsSecretSauce() access doSecretSauce() ? Basically, we have to create a friend relationship between the two classes. Let’s introduce an interface into the impl package:

package impl;
public interface AccessA {
  void doSecretSauce(A a);
}

This interface allows B to access doSecretSauce() in A, if A can provide us an implementation of it. Now we need a place where A can store such an implementation:

package impl;
public class Friends {
  private AccessA accessA;
  public void setAccessA(AccessA aa) {
    accessA = aa;
  }
  AccessA getAccessA() {
    return accessA;
  }
}

Note that the setter is public, so that A can access it, but the getter is package private, so only classes in impl can actually use it. We also need a getInstance() method to get a singleton instance of this class. I assume you know how to implement that ;-). Now we can change the A class to ‘export’ its friend relationship to the impl package:

package api;
import impl.Friend;
import impl.AccessA;

public class A {
  static {
    Friend.getInstance().setAccessA(new AccessAImpl());
  }

  private static class AccessAImpl implements AccessA {
    public void doSecretSauce(A a) {
      a.doSecretSauce();
    }
  }

  void doSecretSauce() {
    // Doing secret sauce here.
  }
}

And finally let B do some secret sauce:

package impl;
public class B {
  void needsSecretSauce() {
    Friends.getAccessA().doSecretSauce(a); // a initialized elsewhere.
  }
}

This solution now is compile time safe, doesn’t raise any security manager concerns, shows best possible performance and is reasonable secure. In OpenJDK there’s the sun.misc.SharedSecret class which basically does what our ‘Friends’ class here does for java.lang and some other packages.