[jsr294-modularity-eg] Changes to the superpackage model
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.
- 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
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.
More information about the jsr294-modularity-eg