JPMS: Modules in the Java Language and JVM

Alex Buckley

2017/6/12 18:57 -0700 [b48f5c3ae99d]

Table of Contents

1. Modules in the Java Language
2. Modules in the JVM

Chapter 1. Modules in the Java Language

Integration of modules in The Java Language Specification, Java SE 9 Edition ("JLS9") is summarized as follows:

  • Modules are motivated at a high level in 1.1 "Organization of the Specification", and in the introduction to Chapter 7 "Packages and Modules" (renamed from "Packages").

    A new section, 7.7 "Module Declarations", specifies the syntax and semantics of named modules. Unnamed modules are specified in 7.7.5, and marginally affect the specification of unnamed packages in 7.4.2.

    The binary form of a module declaration is specified in 13.1, and is largely reliant on 7.7.

  • The "restricted keywords" used in module declarations are introduced in 3.9.

  • Module names are introduced in 6.5 and 6.5.1. Non-normative advice on modules names is given in 6.1.

    However, the name of a reference type in 6.7 and 13.1 does not include the name of the module in which the type was declared (that is, the name of the module with which the compilation unit that contained the type declaration is associated). Therefore, since two modules might contain types with the same binary name, 4.3.4 and 7.6 distinguishes two reference types on the basis of module name and binary name. Two types with binary name P.C are distinct if declared in (compilation units associated with) different modules.

  • Historically, 7.2 and 7.3 defined the concept of a universe of "observable" compilation units, but left their discovery up to a compiler. This remains the case in JLS9, because a specification cannot disprove a compiler's claim that a particular compilation unit in a particular directory does not exist. However, in JLS9, if a compiler does choose to observe an ordinary compilation unit, and does choose to associate it with a modular compilation unit, then the compiler must respect requires directives in the modular compilation unit when determining the meaning of types referenced from the ordinary compilation unit.

    In particular, the compiler must build a universe of "visible" compilation units on a per-module basis when processing ordinary compilation units that it has observed. (The traditional definition of "visible" in 6.4.1 to mean "in scope and not shadowed" has been removed, and the uses in 6.3, 6.4.2, 6.5.5, 6.5.6, 6.5.7, and 15.12.1 have been modified accordingly.)

    Under these rules, it is possible for a given ordinary compilation unit to have "visibility" of ordinary compilation units in a package of another module, even though that package is not exported by its module. The types declared in the ordinary compilation units of that package will nevertheless be inaccessible to code in the given ordinary compilation unit.

    Moreover, under these rules, it is possible for a given ordinary compilation unit to have "visibility" of ordinary compilation units which declare the same package in different modules. That is, the same package may be visible in multiple modules, irrespective of what those modules export. However, the rules of module resolution ensure that a given module enjoys "readability" to no more than one module which exports a package of a given name. The constrained model of "readability" is more helpful when determining the meaning of a package or type name than the less constrained model of "visibility". Accordingly, 7.4.3 introduces the concept of "uniquely visible" to help choose which visible ordinary compilation unit is in play when a package name or type name is given meaning.

    The following sections are changed by the overlaying of module membership and dependencies on the universe of compilation units:

    6.1, 6.3, 6.5.3, 6.5.3.1, 6.5.3.2, 6.5.5.1, 6.5.5.2, 7.5.2
  • Accessibility is defined in 6.6.1. In JLS9, this section distinguishes exported public types (those in packages exported by their module) from unexported public types (those in packages not exported by their module). In effect, JLS9 defines a new level in the type accessibility hierarchy. There are corresponding minor edits to 6.6.2 and 6.6.2.1 for protected types.

    The 6.6.1 definition is referenced widely from Chapter 8 and later. Despite accessibility being a 2-arity function (both accessor and accessee matter), many rules refer to an "accessible" type without specifying the accessor explicitly. For example, 8.1.4 specifies that when class C extends B, B must be an accessible class type; the reader was assumed to understand that B must be accessible from the point of view of C. In JLS9, the reader is still assumed to understand who is the accessor as well as the accessee, but now the accessor's module is as important as the accessor's type.

    The following sections are semantically unchanged by the introduction of the new type accessibility level:

    (Sections marked with a historically referred to 6.6.1, so JLS9 "automatically" prevents the use sites described by these sections from accessing unexported public types of another module, just as JLS8 prevented them from accessing package access types of another package.)

    (Sections marked with p make explicit mention of public (and sometimes protected) without necessarily meaning that a type should be accessible; these sections are occasionally clarified to speak about an accessible type instead.)

    7.5a, 7.5.1a, 7.5.3a, 7.5.4a, 7.6p
    8.1.1a, 8.1.4a, 8.1.5a, 8.2p, 8.3a, 8.4.8p, 8.4.8.1p, 8.4.8.2, 8.4.8.3p
    8.5a, 8.8a, 8.8.3a, 8.8.7.1a, 8.8.10p, 8.9.1a, 8.9.2p, 8.9.3p
    9.1.1p, 9.1.3a, 9.2p, 9.3p, 9.4p, 9.4.1a, 9.5p, 9.6.1p, 9.6.4.4p, 9.7.1a, 9.8p
    10.7p
    12.1.4p 12.3.3p
    15.8.2a, 15.9.1a, 15.9.3a, 15.9.5.1a, 15.11.1a, 15.11.2a
    15.12.2a, 15.12.2.1a, 15.12.2.5a, 15.12.2.6a, 15.12.3a, 15.12.4.3p
    15.13a, 15.13.1a, 15.13.2a, 15.27.3a

    Note 1. There are no changes to member accessibility in 6.6.1. The first reason is that a member's declaring type still dominates access when used as the qualifying type. The second reason, which is more substantive, is that a member may be inherited across a module boundary and then accessed via a qualifying type in the other module. This also explains why inheritance of a class's or interface's public method is unchanged in 8.4.8 and 9.4.1.1; a public method continues to be inherited across a module boundary even when the method's declaring public type is not accessible outside the module. More broadly, public and protected members (including types, per 8.2, and methods, per 8.4.8) are inherited by a subclass in a different module; the usual inter-package rules that apply for access to a protected member still apply when inter-package is also inter-module.

    Note 2. 8.4.8.3 specifies the "no shrinkage of access when overriding or hiding" rule. Because the rule is specified in terms of the access modifiers of the overridden and overriding methods, rather than their accessibility, there is no change in JLS9. On the other hand, 8.8.9 said "The default constructor has the same accessibility as the class."; in JLS9, this is changed to refer to access modifiers instead, since the 6.6.1 rules for accessibility of a constructor are specified in terms of access modifiers.

  • Annotations on module declarations cause minor additions to 9.6.4.1, 9.6.4.6, and 9.7.4, as well as 7.5.1 and 7.5.3.

  • Observations on the binary compatibility of changing a module declaration are given in 13.3.

Chapter 2. Modules in the JVM

Integration of modules in The Java Virtual Machine Specification, Java SE 9 Edition ("JVMS9") is summarized as follows:

  • The binary form of a module declaration is specified in 4.1 and in a new section 4.7.25 "The Module Attribute".

    Module names referenced by a module declaration are described in 4.2.3, and stored in a new kind of constant pool structure specified in 4.4.11 "The CONSTANT_Module_info Structure". Package names referenced by a module declaration are also described in 4.2.3, and stored in a new kind of constant pool structure specified in 4.4.12 "The CONSTANT_Package_info Structure".

    Compilation from module-info.java to module-info.class is discussed in 3.16.

    Auxiliary attributes employed after compilation to define the content of a module are specified in 4.7.26 "The ModulePackages Attribute" and 4.7.27 "The ModuleMainClass Attribute".

  • 5.3.6 "Modules and Layers" is a new section that describes the relationship of classes and class loaders to modules and layers.

  • Accessibility is specified in 5.4.4. In JVMS9, this section (like the corresponding section 6.6.1 in JLS9) distinguishes exported public types (those in run-time packages exported by their run-time module) from unexported public types (those in run-time packages not exported by their run-time module).

    Prior to Java SE 9, it was possible to change the accessibility of a type's member for a specific reflective object in the Java SE Platform API, but this was orthogonal to the accessibility of a type's member resolved via the constant pool. In Java SE 9, it is possible to change the accessibility of a type itself, even when resolved via the constant pool, by using the Java SE Platform API to export a package from a run-time module. While 5.4.4 does respect this increase in a type's accessibility, 5.4.3 clarifies that dynamically exporting a package in this way does not change the accessibility of a previously inaccessible type.