Oracle Blog

Gilad Bracha's Sun Weblog

Developing Modules for Development

I can’t control my masochistic tendencies, so I’m about to start yet another JSR. This time, the topic is modularity. Specifically, some notion of modules for development of Java programming language source code.

The upcoming JSR should not be confused with JSR 277, which deals with deployment modules - you know, JAR files and packaging, run time name space issues in support of side-by-side deployment and the class loading issues. They have the hard problem, and I’ve been quite involved in their discussions and in the design of a reflective module API that looks like it will end up being a key component of their solution.

No, the new language modules JSR deals with relatively simple issues.

The most important of these is information hiding. Currently, the only module-like mechanism available in the Java programming language is the package. As a namespace mechanism, packages have been very successful: the inverted internet domain convention has worked very well, and has been an important contributing factor in the success of the Java platform.

Alas, as a modularity mechanism, packages leave a lot to be desired. Here is the basic problem: suppose you are building a software application. Your system consists of several parts/subsystems.

These subsystems are typically more tightly coupled to each other than to the outside world. So you’d like to each to expose an internal API available to the other subsystems but not to external clients. To do this, you find that you have to place all the subsystems in one big package. The internal API is then package-private. This approach has problems. Your system is all in one giant, unwieldy package. You cannot protect elements of a subsystem from other subsystems.

The obvious alternative is to place each subsystem in its own package. Now the package structure nicely mirrors the design of your application. Each subsystem can protect its internals from the rest of the system. However, you cannot provide that privileged internal API you wanted. You can make things public so that other subsystems can get at them - but now you’ve gone and exposed them to the whole universe.

Here is a strawman solution: we introduce superpackages (The name was NOT my idea). A superpackage lists a series of member packages. Public members of member packages are accessible in all other member packages - but not to the wider world. Only members explicitly exported by the superpackage are available outside the superpackage. This might look something like this:

super package com.sun.myModule {

export com.sun.myModule.myStuff.\*;

export com.sun.myModule.yourStuff.Interface;

com.sun.myModule.myStuff;

com.sun.myModule.yourStuff;

com.sun.SomeOtherModule.theirStuff;

org.someOpenSource.someCoolStuff;

}

Don’t fuss over the syntax. It is bound to change.

Tangent: Not that syntax doesn’t matter - but semantics are a much deeper issue. That is in fact why most people focus on syntax. It doesn’t require much expertise or understanding, so everyone can have an opinion. This phenomenon is closely related to Parkinson’s law of Triviality:

The time spent on any item of the agenda will be in inverse proportion to the sum involved.

So, repeat after me: fussing over syntax is for the language-design challenged, and for marketing to the illiterati.

Another, less critical issue we’d like to deal with is separate compilation. Today, if you import code from another package, you need to have that code available - either as source or as binary. In principle, all you really need are the declarations of the public members you are using. You can get around this fairly easily by constructing dummy declarations - but it is an ugly nuisance.

Here is an example:

package interface fully.qualified.packageName;

// implicitly public types and members

class C implements fully.qualified.interface {

String someMethod();

C(int i);

protected Object aFieldName;

}

Remember, this is a strawman; there should be a JSR dealing with this soon, and the expert group will resolve all of these issues. For example, it will have to decide whether superpackages nest, and what the exact VM access rules are, what the source syntax and binary formats are etc. And very importantly, all of this stuff will have to play well with JSR 277, which is why the two EGs are certain to have several members in common.