Sunday, May 11, 2008

JSR 277 and the module keyword

JSR 277 defines the modularity extensions proposed for Java SE 7 (JSR 294 is no longer contributing to the modularity discussion). The modularity proposal has been completely overhauled. The new proposal is (rumored to be) streamlined and vastly improved. JSR 277 draft 2 is coming shortly. The JSR covers a lot of ground, but the biggest change the JSR is the new 'module' keyword.

Early drafts of the module JSRs tried to reduce syntactic changes by redefining the semantics of the 'public' access modifier according to a separate compilation unit (super-package.java). This meant affecting not just the java language, but the entire java platform, as the ACC_PUBLIC flag in a classfile would be redefined and would affect java AND every non-Java language compiler that targets the JVM. Scary! Fortunately the newly-strengthed JSR 277 group (primarily Alex Buckley and Stanley Ho) has completely overhauled the module proposal, and the new draft JSR promises to be both simpler and better.

The new proposal includes the following points:
  • retain the current meaning of 'public' and the ACC_PUBLIC flag (whew!).
  • introduce the 'module' access modifier for types and members. Classfiles reify module access using the new ACC_MODULE flag.
  • any compilation unit (i.e. a class) whose types have the 'module' access modifier, or who access a 'module' type or member, identify their module via a single 'module ;' declaration.

One other tidbit: the 'module' keyword is not a fully reserved keyword. It's only contextually reserved, in a bid to lessen the impact of adding a new keyword. For example, you can still have a class named 'Module'. This sounds small, but will make adoption of Java SE 7 much easier if you have a large existing codebase. Making 'enum' a reserved keyword caused major havoc for larger organizations trying to adopt jdk 1.5.

The new modularity system can be as simple as making a 'module' declaration and optionally scoping a class or member 'module'. Any type or member scoped module (aka 'module-private') is accessible by other classes within the module, but classes outside the module cannot access it.

Here's a simple example of an interface scoped module, which is implemented by a class that is also a member of that module:

module a;
package a.b;
module interface Foo {
  ...
}

module a;
package a.b.c;
class Bar implements Bar {
  ...
}

The module declaration imposes, for the first time, a real package hierarchy in java. Any class or package of a module must be in a package or sub-package of the module. A class may belong to only a single module. And finally, modules may not have submodules.

The updated draft of JSR 277 will hopefully be out shortly.

P.S. I'm ignoring the JSR 277 vs OSGi controversy. For the moment.