{ by david linsin }

March 10, 2008

JSR 294 Superpackages

In "The Open Road", which contains a series of blogs about the upcoming Java SE 7 release, Elliotte Rusty Harold wrote about JSR 294 aka superpackages.

Java's package mechanism today, is basically broken, because there is no hierarchical model. Hence, there is no way to completely hide your implementation from the outside world and no true separation of interfaces and implementation. One could argue that you could mark your methods "private" or "package private", but you will be running into situations - sooner or later - where you want them to be accessible not only within the same package, but also from subpackages of their hierarchy.

JSR 294 is trying to address this problem. The idea is to create a superpackage around a set of packages, which are called "members". Those members contain classes, so called "exports", which define access points to the superpackage from outside world. The most compelling advantage of this JSR, is fact that access to members are restricted by the compiler. You will get a compile time error, if you try to use classes of a superpackage, which are not exported. Unfortunately there is no way to restrict access to methods, which would come in handy.

Here is an example of a superpackage definition, which would reside in a file called super-package.java in "de/linsin/sample":

superpackage de.linsin.sample {
// contained in superpackage
member de.linsin.sample.p1
member de.linsin.sample.p2

// access points
export de.linsin.sample.p1.SampleClass
export de.linsin.sample.p2.SampleSingleton

The first thing that came to my mind when I saw this was OSGi. You can do the same things, using the OSGi Manifest headers:

Bundle-SymbolicName: tutorial.example2
Bundle-Version: 1.0.0
Bundle-Activator: tutorial.example2.Activator
Export-Package: tutorial.example2.service
Import-Package: org.osgi.framework

In addition to that, you can add a version or range of versions to imports and exports, to enforce the OSGi classloader to only give you that version or any version in that range.

Comparing OSGi to Java is not fair and I have to mention, that OSGi is much more powerful, than what I pointed out here. A better comparison would be Java to Scala:

package com.codecommit.mypackage.impl

class MyClass {
private[mypackage] def myMethod = "test"

The example was taken from Daniel Spiewak's tutorial on Scala.

Scala lets you denote classes and methods with an access modifier, which can either be an enclosing package or class. It enables true compile-time checked separation of interfaces and implementation with a very neat syntax.

I really like the idea of JSR 294, but in my opinion the implementation is rather unfortunate. If you look at the example in Elliotte Rusty Harold's article, which shows how to hide a method from the outside world, you get an idea of what I'm talking about. I don't want to create extra classes, in order to hide any methods.

However, JSR 294 is still in early draft review, so there is still time to fix the broken implementation.



  • mail(dlinsin@gmail.com)
  • jabber(dlinsin@gmail.com)
  • skype(dlinsin)