Draft 2007-03-16
This is a straw-man proposal for JSR 294 Superpackages written by Andreas Sterbenz and Alex Buckley. It is based on the concepts described by Gilad Bracha in the JSR submission and the JSR 277 whitepaper by Gilad Bracha and Michal Cierniak.
As described in the JSR 294 submission (Improved Modularity Support in the Java Programming Language), we propose to address two problems: information hiding and separate compilation. This document describes a proposal for information hiding using a new entity called superpackage. Separate compilation will be the topic of another document.
public
to access it from the different packages of the project, but that also
makes it available to packages outside the project.
A superpackage is declared in a Java source file. It defines:
This source file is processed by a Java compiler similarly to
other source files. The result of the compilation is a
.superpackage file, analogous to a .class
file. The format of the superpackage file is TBD.
Note: in earlier discussions the superpackage
file was called a module file. The proposed name
was changed to avoid confusion with the Module Archive format
defined by JSR 277.
File example/foo/myapp/super-package.java:
// Declare the superpackage
superpackage example.foo.myapp {
// all types in the listed packages are members of this superpackage
member package example.foo.myapp, example.foo.myapp.processing;
// list of exported types
export example.foo.myapp.Main, example.foo.myapp.Helper;
}
File example/foo/myapp/Main.java
package example.foo.myapp;
public class Main {
public Main() { ... }
}
File example/foo/myapp/Parser.java
package example.foo.myapp;
public class Parser {
public Parser() { ... }
}
[Other files omitted]
example/foo/myapp/super-package.java)
defines the members of the superpackage example.foo.myapp as the packages
example.foo.myapp and example.foo.myapp.processing.
The exported types are example.foo.myapp.Main and
example.foo.myapp.Helper. These are the only types that are
accessible outside the superpackage example.foo.myapp. The class
example.foo.myapp.Parser is a public non-exported class.
That means that it is not accessible by types outside
the superpackage example.foo.myapp.
The list of exported types may include * wildcards to
export an entire package. The wildcard is expanded by the Java
compiler to full list of type names.
As with the existing Java access control mechanisms, the superpackage access control is enforced by the Java compiler at compilation time and the Java virtual machine at runtime (JVMS 5.4.4).
Note that this proposal avoids having the source of each Java type declare its superpackage membership. This approach was chosen in order to make it easier to migrate existing Java source code to superpackages. However, Java class files that are part of a superpackage will contain an appropriate attribute that indicates the name of the superpackage. It is assumed that the Java compiler is able to determine superpackage membership from the superpackage source file or in some other way, for example using commandline arguments.
superpackage file is reified at runtime using
a reflective API in the style of java.lang.Class.
This class java.lang.Superpackage allows retrieval
of the information declared in the superpackage source file,
such as the names of exported types.
A method getSuperpackage() is added to
java.lang.Class, which returns the superpackage
object associated with a class, or null if the class is not
a member of a superpackage.
A superpackage file is loaded via a ClassLoader. A superpackage is always defined by the same ClassLoader as its member classes.
A nested superpackage is declared by listing the name of the enclosing superpackage in its superpackage source file, and by the enclosing superpackage listing the nested superpackage as a member.
The enclosing superpackage can declare a nested superpackages as exported. If exported, the exported types of the nested superpackage are accessible outside the enclosing superpackage. If not exported, the exported types of the nested superpackage are accessible to other types in the enclosing superpackage but not outside the enclosing superpackage.
example.bar.lib
which contains the package example.bar.lib and
the nested superpackages example.bar.lib.net
and example.bar.lib.xml.
The type example.bar.lib.Table is exported by
example.bar.lib and therefore accessible by
other code. The nested superpackage example.bar.lib.net
is also declared as exported. This means that all types
it exports - example.bar.lib.net.* - are also accessible
to code outside the example.bar.lib superpackage.
The nested superpackage example.bar.lib.xml is
not exported by example.bar.lib. This means that
the exported types from example.bar.lib.xml are accessible
to code in example.bar.lib - including its nested
superpackage example.bar.lib.net - but they
are not accessible to code outside of example.bar.lib.
File example/bar/lib/super-package.java:
// Declare the superpackage
superpackage example.bar.lib {
// member packages
member package example.bar.lib;
// member superpackages
member superpackage example.bar.lib.net, example.bar.lib.xml;
// list of exported types
export example.bar.lib.Table;
export superpackage example.bar.lib.net;
}
File example/bar/lib/net/super-package.java:
// First nested superpackage
superpackage example.bar.lib.net member example.bar.lib {
// member packages
member package example.bar.lib.net, example.bar.lib.http;
// list of exported types
export example.bar.lib.net.*;
}
File example/bar/lib/xml/super-package.java:
// Second nested superpackage
superpackage example.bar.lib.xml member example.bar.lib {
// member packages
member package example.bar.lib.xml, example.bar.lib.xml.internal;
// list of exported types
export example.bar.lib.xml.*;
}