[jsr294-modularity-eg] Changes to the superpackage model

Alex Buckley Alex.Buckley at Sun.COM
Wed Mar 26 17:40:52 EDT 2008


I propose a change to the nomenclature and design of superpackages.

JSR 294 has so far aimed to minimize syntactic changes in existing 
source code, at the cost of redefining the semantics of 'public' 
according to a separate compilation unit (super-package.java).

There are some problems with that aim:

- Redefining an existing access modifier is not respectful of millions
   of developers' investment in the traditional accessibility model of
   the Java platform. I say "platform" not "language" because redefining
   'public' means redefining the ACC_PUBLIC flag in a classfile, and that
   affects every non-Java language compiler targeting the JVM.

- Minimizing changes in existing source code is not respectful of the
   Java language principle that "Reading is more important than than
   writing". To save one developer from writing 'superpackage S;' in
   a source file, we impose a burden on every subsequent developer who
   reads the source file and wants to reason about accessibility.

- Even if a separate export list is thought desirable (and it surely
   has a valuable documentary role), it is insufficient to have only
   simple regexs ('export foo.*'). A discussion thus starts about
   what regexs the JLS should support, which is frankly a distraction
   from bigger issues and provides yet more complexity for a developer
   trying to determine what is accessible.

My proposal:

- Retain the current meaning of 'public' and ACC_PUBLIC.

- Introduce a 'module' access modifier for types and members. A new
   ACC_MODULE flag (0x8000) reifies module accessibility in a classfile.

- Require any compilation unit whose types are 'module'-private or
   access module-private types/members, to identify their module
   membership via a single 'module M;' declaration.

   (It is not possible to make 'module M;' optional in these
   circumstances. In theory, a compiler switch can identify a class's
   module membership, but the JLS cannot talk about compiler switches;
   yet it must know module membership to determine accessibility.)

   A classfile has a Module attribute to reify module membership.

- Since globally public types are 'public' and module-private types are
   'module' qualified, there is no need for super-package.java. Only if
   module-level annotations are used does the following file, analogous
   to package-info.java, come into play:

   // This file is M/module-info.java and compiles to M/module-info.class
   @Foo
   @Version(...)
   @Imports(...)
   module M;

Implications of the proposal:

- There are no nested superpackages. The EG has never supported them.
   I personally continue to support them, and think there is an
   interesting design space for nesting with decentralized module
   declarations. But it can be left for another day.

- super-package.class no longer appears as an authoritative member and
   export list. This is a non-issue in security terms, since the file was
   always trivially changeable.

- module-info.class will be reified to support enumerating its
   annotations, but the 294 reflection API will not be able to enumerate
   a module's member and export lists. (Akin to how a package's member
   types cannot be enumerated.) Stanley Ho and I will work to simplify
   this API in general and unify it with 277's API.

- super-package.class no longer needs to be regenerated when a new type
   is added to a package P and 'export P.*;' is in super-package.java.

- super-package.class no longer needs to be read by the VM when loading
   a class. A classfile's accessibility is completely self-described.

- A JAM file in JSR 277 can be built by examining the classfiles named
   by the deployer (e.g. as parameters on the 'jam' command line):
   - The member list is available trivially.
   - The export list is the set of public types in the member list.
   - The import list is denoted by @Imports in module-info.java.

With this proposal, a module in JSR 294 continues to be the foundation 
of a module in JSR 277, but getting started with just a 294 module is 
now easier because the 'module' modifier is a simple and consistent 
extension of the traditional accessibility model (in line with the 
second goal of the 294 strawman). Comments are welcome.

Alex


More information about the jsr294-modularity-eg mailing list