One interesting issue when writing a runtime class library for Java is how to give implementation packages, whether they be in gnu.* or com.sun.*, specialised access to the core runtime classes like those in java.lang. We ran across this problem again recently with GNU Classpath when trying to write CPStringBuilder. This is a StringBuilder variant that differs in how it utilises its internal character array. StringBuffer and StringBuilder both maintain their own character array throughout their life, creating a new larger one and copying when appropriate. When toString() or substring(int,int) is called, the new String object is given a copy of the array.

CPStringBuilder instead optimises for the frequent cases where a StringBuilder is created, used to build a String and then discarded after toString() is called. It does so by handing a reference to the character array to the new String object on creation. Once this is done, it flags internally that the array has been used and creates a new one if any further writes are requested. Thus, using CPStringBuilder should always be one copy more efficient than using StringBuilder or StringBuffer (possibly even creating just a single array if the final string is within the initial capacity) and we now use it internally when the builder does not need to be thread-safe.

The problem with implementing this is that it requires passing the array to the constructor of the String object. There is no such constructor in the public API for String, although Classpath has had a package-private one for sometime (GCJ and String itself already use it). But how do we access this from the gnu.java.lang package? Our current method is to use reflection, and thus we have VMCPStringBuilder so VMs can optimise this natively.

When looking through OpenJDK for the VM project, I noticed that they have a rather interesting solution to this. This is encapsulated in sun.misc.SharedSecrets. This class provides access to instances of a number of public interfaces, such as sun.misc.JavaLangAccess. The actual implementations are provided as inner classes in the appropriate package e.g. java.lang, where it has access to the private and package-private variables and methods within. For instance, JavaLangAccess provides access to the constant pool for a particular class.

The only noticeable negative side effect of this is that any external class may also call these methods. For example:

import sun.misc.SharedSecrets;

public class TestSecrets
{
  public static void main(String[] args)
  {
    System.out.println(SharedSecrets.getJavaLangAccess().getConstantPool(String.class));
  }
}

whereas the equivalent for GNU Classpath:

import gnu.java.lang.VMCPStringBuilder;

public class TestCPSecrets
{
  public static void main(String[] args)
  {
    System.out.println(VMCPStringBuilder.toString(new char[]{'H','e','l','l','o'},0,5));
  }
}

fails to compile because VMCPStringBuilder is package-private (although the equivalent is possible by using CPStringBuilder in this case). As a result, it becomes slightly more important to ensure that the possible damage from using these classes is limited.

That said, this may be an interesting and more efficient method for us to look into for GNU Classpath.