Oracle Blog

On the design and specification of Java

Peter Kriens on language-level modularity

Peter Kriens, the OSGi spec lead and official evangelist, takes a positive view of language-level modularity. His focus on "requirements, not solutions" is especially helpful. Here are some responses to his points:

Module-private interfaces

There is little difficulty in allowing an interface to be module-private, since it can already be package-private or public. As for interface members, it was a nice simple approach back in the day to make them automatically "accessible outside my package", since that's completely what 'public' meant. (Of course the cost was excessive exposure of implementation methods.) Now that public is no longer the only "outside my package" level, it makes sense to allow module-private interface members:

Now that JSR 277 is the place for Java modularity, look for a unified module reflection API soon. Stanley Ho and I do understand why dynamic membership is important.

Module export

Peter identifies an additional accessibility level, 'export', between module-private and globally public. I might call it multi-module-private, since a type/member marked 'export' is accessible in its own module and from any module which imports that module. The difficulty is that the VM won't know about module imports so can't determine which other modules can access a multi-module-private type/member. The same is true of javac - it generally won't know if the caller's module imports the callee module where the 'export' type/member lives. (There will be a way to compile programs in the context of a runtime module system, but it will not be mandatory because people should be able to use modules simply as "better packages" without deployment overhead like module dependencies and packaging.)

Scoping

Peter proposes to qualify type names in classfiles with their declaring module. This is not strictly necessary because when the VM resolves a module-private type/member, it must compare the caller's module with the callee's module. It cannot rely on the caller's classfile claiming that the callee's module is so-and-so, hence I don't see the benefit in embedding the callee module in the caller. Indeed, this is the kind of excessive two-way dependency we're now trying to avoid. Also, having a caller commit to which module declares a type seems contrary to having the runtime obtain types from arbitrary modules (e.g. in the context of an import-by-package dependency).

Versioning

A standard version schema for Java types would be very interesting but not in the Java SE 7 time frame. We all need to think about this more. (See Alexander Krapf at JavaPolis and "UpgradeJ: Incremental Typechecking for Class Upgrades" by Bierman, Parkinson and Noble at ECOOP 2008.)