JPMS: Modules in the Java Language and JVM

Alex Buckley

2017/2/23 15:27 -0800 [9d1c4ba194e3]

Table of Contents

1. Modules in the Java Language
1.1. Module Declarations
1.1.1. Dependences
1.1.2. Access Control
1.1.3. Service Consumption
1.1.4. Service Provision
2. Modules in the JVM
2.1. Binary form of a module declaration
2.2. The Module attribute
2.3. The ModulePackages attribute
2.4. The ModuleMainClass attribute
2.5. The CONSTANT_Module_info Structure
2.6. The CONSTANT_Package_info Structure

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 introductions to chapters 7 and 8.

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

  • Module names are introduced in 6.5 and 6.5.1. The binary form of a module declaration is specified in 13.1, and is largely reliant on module names.

    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, the JLS defined the concept of a universe of "observable" compilation units, but left the actual discovery and ingestion of compilation units entirely up to a compiler. This remains the case in JLS9, even to the extent that a compiler is not forced (in fact, cannot be forced) to observe any particular compilation unit in any particular directory. 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 clauses 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 ingested. (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.)

    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.2, 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 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
    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.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. requires produces a deprecation or removal warning if it refers to an ordinarily or terminally deprecated module; similarly if uses and provides refer to deprecated types. On the other hand, exports and opens never produce deprecation or removal warnings. Even if the package they expose is deprecated, the package and the module are under the control of the same author so there is no "news" in a warning; and, if the friend module mentioned by a qualified exports or opens is deprecated, there is no value in a warning because the only thing that the exposing module can do is suppress it.

  • The section below, on the well-formedness of module declarations, will constitute section 7.7 of JLS9.

1.1. Module Declarations

A compilation unit (JLS 7.3) may contain a module declaration, in which case the filename of the compilation unit is typically module-info.java.


CompilationUnit:
  [PackageDeclaration] {ImportDeclaration} {TypeDeclaration}
  {ImportDeclaration} ModuleDeclaration

ModuleDeclaration:
  {Annotation} [openmodule Identifier {. Identifier} { {ModuleStatement} }

ModuleStatement:
  requires {RequiresModifier} ModuleName ;
  exports PackageName [to ModuleName {, ModuleName}] ;
  opens PackageName [to ModuleName {, ModuleName}] ;
  uses TypeName ;
  provides TypeName with TypeName {, TypeName} ;

RequiresModifier: one of
  transitive static

ModuleName:
  Identifier
  ModuleName . Identifier

Example:

@Foo(1) @Foo(2) @Bar
module M.N {
  requires A.B;
  requires transitive C.D;
  requires static E.F;
  requires transitive static G.H;

  exports P.Q;
  exports R.S to T1.U1, T2.U2;

  opens P.Q;
  opens R.S to T1.U1, T2.U2;

  uses V.W;
  provides X.Y with Z1.Z2, Z3.Z4;
}
@Foo(1) @Foo(2) @Bar
open module M.N {
  requires A.B;
  requires transitive C.D;
  requires static E.F;
  requires transitive static G.H;

  exports P.Q;
  exports R.S to T1.U1, T2.U2;

  uses V.W;
  provides X.Y with Z1.Z2, Z3.Z4;
}

open, module, requires, transitive, exports, opens, to, uses, provides, and with are restricted keywords (i.e. they are keywords solely where they appear as terminals in ModuleDeclaration, and are identifiers everywhere else).

A module declaration introduces a module name that can be used in other module declarations to express relationships between modules. (Requirement) A module name consists of one or more Java identifiers (JLS 3.8) separated by "." tokens. In the declaration of a module name (after module) and in any use of a module name (by requires, exports, or opens), every identifier in the name must end with a Java letter, or a compile-time error occurs.

There is no obscuring (JLS 6.4.2) between the name of a module and the name of a variable, type, or package; thus, modules may share names with variables, types, and packages, though it is not necessarily recommended to name a module after a package it contains.

A normal module, without the open modifier, grants access at compile time and run time to types in only those packages which are explicitly exported. In addition, a normal module grants reflective access to types in only those packages which are explicitly opened.

An open module, with the open modifier, grants access at compile time to types in only those packages which are explicitly exported, but grants access at run time to types in all its packages, as if all packages had been exported. In addition, an open module grants reflective access to types in all its packages.

For code outside the module, the access granted at compile time and run time to types in exported packages is specifically to the public and protected types in those packages, plus the public and protected members of those types. However, for code outside the module, no access is granted at compile time and run time to types in packages which are not exported. (This applies regardless of whether reflective access is granted.) Code inside the module may access public and protected types of all packages in the module.

1.1.1. Dependences

The requires statement takes a qualified identifier indicating the name of a module on which the current module has a dependence. (Requirement)

A requires statement must not appear in the declaration of the java.base module, or a compile-time error occurs, because it is the primordial module and has no dependences. (Compare JLS 8.1.4)

It is a compile-time error if the named module is not observable.

It is a compile-time error if more than one requires statement in a module declaration specifies the same module name.

It is a compile-time error if the declaration of a module expresses a dependence on itself, either directly or indirectly.

The requires keyword may be followed by the modifier transitive. This causes any module which depends on the current module to have an implicitly declared dependence on the module specified by the requires transitive statement.

If the declaration of a module does not express a dependence on the java.base module, and the module is not itself java.base, then the module has an implicitly declared dependence on the java.base module.

The requires keyword may be followed by the modifier static. This specifies that the dependence, while mandatory at compile time, is optional at run time.

1.1.2. Access Control

The exports statement takes a qualified identifier indicating the name of a package to be exported by the current module. This makes public and protected types in the package, and their public and protected members, be accessible to code in other modules. (Requirement)

The opens keyword takes a qualified identifier indicating the name of package to be opened by the current module. This makes public and protected types in the package, and their public and protected members, be accessible to code in other modules at run time only. It also makes all types in the package, and all their members, be accessible via the reflection libraries of the Java SE Platform.

It is a compile-time error if the package specified by exports is not declared by a compilation unit associated with the current module.

It is permitted for opens to specify a package which is not declared by a compilation unit associated with the current module. (If the package should happen to be declared by an observable compilation unit associated with another module, the opens statement has no effect on that other module.)

It is a compile-time error if more than one exports statement in a module declaration specifies the same package name.

It is a compile-time error if more than one opens statement in a module declaration specifies the same package name.

It is a compile-time error if an opens statement appears in the declaration of an open module.

If an exports or opens statement has a to clause, then the statement is qualified; otherwise, it is unqualified. For a qualified statement, the public and protected types in the package, and their public and protected members, are accessible solely to code in the modules specified in the to clause. For an unqualified statement, these types and their members are accessible to code in any module. (Requirement)

It is permitted for the to clause of an exports or opens statement to specify a module which is not observable.

It is a compile-time error if the to clause of a given exports statement specifies the same module name more than once.

It is a compile-time error if the to clause of a given opens statement specifies the same module name more than once.

1.1.3. Service Consumption

The uses statement in a module declaration specifies a service interface which the current module may discover via java.util.ServiceLoader. (Requirement)

The service interface may be declared in the current module or in another module. If the service interface is not declared in the current module, then the service interface must be accessible to code in the current module, or a compile-time error occurs.

The service interface may be a class type, an interface type, or an annotation type. It is a compile-time error if a uses statement specifies an enum type (JLS 8.9) as the service interface.

It is a compile-time error if more than one uses statement in a module declaration specifies the same service interface.

1.1.4. Service Provision

The provides statement specifies a service interface for which the with clause specifies one or more possible service implementations to java.util.ServiceLoader. (Requirement)

The service interface may be declared in the current module or in another module. If the service interface is not declared in the current module, then the service interface must be accessible to code in the current module, or a compile-time error occurs.

Every service implementation must be declared in the current module, or a compile-time error occurs.

The service interface must be a class type, an interface type, or an annotation type. It is a compile-time error if a provides statement specifies an enum type (JLS 8.9) as the service interface.

Every service implementation must be a class type or an interface type, that is public, and that is top level or nested static, or a compile-time error occurs.

If a service implementation explicitly declares a public constructor with no formal parameters, or implicitly declares a public default constructor (JLS 8.8.9), then that constructor is called the provider constructor.

If a service implementation has a public static method called provider with no formal parameters, then that method is called the provider method.

If a service implementation has a provider method, then its return type must i) either be declared in the current module, or be declared in another module and be accessible to code in the current module; and ii) be a subtype of the service interface specified in the provides statement; or a compile-time error occurs.

While a service implementation specified by a provides statement must be declared in the current module, its provider method may have a return type that is declared in another module.

If a service implementation does not have a provider method, then that service implementation must have a provider constructor and must be a subtype of the service interface specified in the provides statement, or a compile-time error occurs.

It is a compile-time error if more than one provides statement in a module declaration specifies the same service interface.

It is a compile-time error if the with clause of a given provides statement specifies the same service implementation more than once.

Chapter 2. Modules in the JVM

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

  • 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 defined 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.

  • The sections below will contribute to chapter 4 of JVMS9.

2.1. Binary form of a module declaration

A compilation unit that contains a module declaration is compiled to a ClassFile structure.

By convention, the name of a compilation unit that contains a module declaration is module-info.java, echoing the package-info.java convention for a compilation unit that contains solely a package declaration. Consequently, by convention, the name for the compiled form of a module declaration is module-info.class.

A new flag in the ClassFile.access_flags item, ACC_MODULE (0x8000), indicates that the ClassFile declares a module. ACC_MODULE plays a similar role to ACC_ANNOTATION (0x2000) and ACC_ENUM (0x4000) in flagging this ClassFile as "not an ordinary class". ACC_MODULE does not describe accessibility of a class or interface.

If ACC_MODULE is set in ClassFile.access_flags, then no other flag in ClassFile.access_flags may be set, and the following rules apply to the rest of the ClassFile structure:

  • major_version, minor_version: 53.0 (i.e. Java SE 9 and above)

  • this_class: module-info

  • super_class, interfaces_count, fields_count, methods_count: zero

  • attributes: One Module attribute must be present. Except for Module, ModulePackages, ModuleMainClass, InnerClasses, SourceFile, SourceDebugExtension, RuntimeVisibleAnnotations, and RuntimeInvisibleAnnotations, none of the pre-defined attributes in JVMS 4.7 may appear.

The Module attribute is explicit about the module's dependencies; there are no implicit requires statements at the ClassFile level. If the requires_count item is zero, then the Java Virtual Machine does not infer the existence of a requires table nor any particular entry therein. java.base is the only module in which a zero requires_count is legal, because it is the primordial module; for every other module, the Module attribute must have a requires table of at least length one, because every other module depends on java.base. If the source of a module declaration (except java.base) does not state its dependence on java.base explicitly, then a compiler must emit an entry for java.base in the requires table and flag it as ACC_MANDATED to denote that it was implicitly declared. (Compile-time)

The Module attribute is also explicit about the module's consumption and provision of services; there are no implicit uses and provides statements at the ClassFile level.

The story for encapsulation is more nuanced:

  • For an open module, the Module attribute is implicit about the module's opened packages. Even though the opens_count item is zero (indeed, must be zero), all packages of the module are opened, as if by unqualified opens statements.

  • For a normal module, the Module attribute is explicit about the module's exported packages and opened packages; there are no implicit exports or opens statements at the ClassFile level. If the exports_count item or opens_count item is zero, then the Java Virtual Machine does not infer the existence of an exports table or opens table, nor the existence of any particular entry therein.

    However, if the exports_count item or opens_count item is nonzero, then an entry of the exports table or opens table may use a lack of information to convey something meaningful. Namely, if an entry's exports_to_count item or opens_to_count item is zero and thus the exports_to_index table or opens_to_index table is empty, the Java Virtual Machine allows code in all modules to access types of the exported or opened package.

Module names that are referenced from the Module attribute are stored in CONSTANT_Module_info structures in the constant pool. Such structures are legal only if ACC_MODULE is set in ClassFile.access_flags. Each CONSTANT_Module_info structure wraps a CONSTANT_Utf8_info structure that denotes the module name. Module names may be drawn from the entire Unicode codespace, except for the constraint that they must not contain any code point in the range '\u0000' to '\u001F' inclusive. Module names are not encoded in "internal form" like class and interface names, that is, the ASCII periods (.) that separate the identifiers which make up a module name are not replaced by ASCII forward slashes (/).

The ASCII backslash (\) is reserved for use as an escape character in CONSTANT_Utf8_info structures that denote module names. It must not appear in such structures unless it is followed by an ASCII backslash, an ASCII colon (:), or an ASCII at-sign (@). The ASCII character sequence \\ may be used to encode a backslash in a module name.

The ASCII colon (:) and at-sign (@) are reserved for future use in CONSTANT_Utf8_info structures that denote module names. They must not appear in such structures unless they are escaped. The ASCII character sequences \: and \@ may be used to encode a colon and an at-sign in a module name.

Package names referenced from the Module attribute are stored in CONSTANT_Package_info structures in the constant pool. Such structures are legal only if ACC_MODULE is set in ClassFile.access_flags. Such structures wrap CONSTANT_Utf8_info entries which represent package names encoded in internal form.

2.2. The Module attribute

The Module attribute is a variable-length attribute in the attributes table of a ClassFile structure. The Module attribute indicates the required modules and exported packages of a module, as well as services used by and provided by a module.

There may be at most one Module attribute in the attributes table of a ClassFile structure.

Module_attribute {
    u2 attribute_name_index;
    u4 attribute_length;

    u2 module_name_index;
    u2 module_flags;
    u2 module_version_index;

    u2 requires_count;
    {   u2 requires_index;
        u2 requires_flags;
        u2 requires_version_index;
    } requires[requires_count];

    u2 exports_count;
    {   u2 exports_index;
        u2 exports_flags;
        u2 exports_to_count;
        u2 exports_to_index[exports_to_count];
    } exports[exports_count];

    u2 opens_count;
    {   u2 opens_index;
        u2 opens_flags;
        u2 opens_to_count;
        u2 opens_to_index[opens_to_count];
    } opens[opens_count];

    u2 uses_count;
    u2 uses_index[uses_count];

    u2 provides_count;
    {   u2 provides_index;
        u2 provides_with_count;
        u2 provides_with_index[provides_with_count];
    } provides[provides_count];
}
attribute_name_index

The value of the attribute_name_index item must be a valid index into the constant_pool table. The constant_pool entry at that index must be a CONSTANT_Utf8_info structure representing the string "Module".

attribute_length

The value of the attribute_length item is the length of the attribute excluding the initial six bytes.

module_name_index

The value of the module_name_index item must be a valid index into the constant_pool table. The constant_pool entry at that index must be a CONSTANT_Module_info structure denoting the current module.

module_flags

The value of the module_flags item is as follows:

0x0020 (ACC_OPEN)

Indicates that this module is open.

0x1000 (ACC_SYNTHETIC)

Indicates that this module was not explicitly or implicitly declared.

0x8000 (ACC_MANDATED)

Indicates that this module was implicitly declared.

module_version_index

The value of the module_version_index item must be either zero or a valid index into the constant_pool table. If the value of the item is zero, then no version information about the current module is present. If the value of the item is nonzero, then the constant_pool entry at that index must be a CONSTANT_Utf8_info structure representing the version of the current module.

requires_count

The value of the requires_count item indicates the number of entries in the requires table.

If the current module is java.base, then requires_count must be zero. (Compile-time)

requires[]

Each entry in the requires table specifies a dependence of the current module. (Compile-time) The items in each entry are as follows:

requires_index

The value of the requires_index item must be a valid index into the constant_pool table. The constant_pool entry at that index must be a CONSTANT_Module_info structure denoting a module on which the current module depends.

At most one entry in the requires table may specify a module of a given name with its requires_index item. (Compile-time)

requires_flags

The value of the requires_flags item is as follows:

0x0020 (ACC_TRANSITIVE)

Indicates that any module which depends on the current module, implicitly declares a dependence on the module indicated by this entry.

0x0040 (ACC_STATIC_PHASE)

Indicates that this dependence is mandatory in the static phase, i.e., at compile time, but is optional in the dynamic phase, i.e., at run time.

0x1000 (ACC_SYNTHETIC)

Indicates that this dependence was not explicitly or implicitly declared in the source of the module declaration.

0x8000 (ACC_MANDATED)

Indicates that this dependence was implicitly declared in the source of the module declaration.

requires_version_index

The value of the requires_version_index item must be either zero or a valid index into the constant_pool table. If the value of the item is zero, then no version information about the dependence is present. If the value of the item is nonzero, then the constant_pool entry at that index must be a CONSTANT_Utf8_info structure representing the version of the module specified by requires_index.

Unless the current module is java.base, exactly one entry in the requires table must have both a requires_index item which indicates java.base and a requires_flags item which has the ACC_SYNTHETIC flag not set. (Compile-time)

exports_count

The value of the exports_count item indicates the number of entries in the exports table.

exports[]

Each entry in the exports table specifies a package exported by the current module, such that public and protected types in the package, and their public and protected members, may be accessed from outside the current module, possibly from a limited set of "friend" modules.

The items in each entry are as follows:

exports_index

The value of the exports_index item must be a valid index into the constant_pool table. The constant_pool entry at that index must be a CONSTANT_Package_info structure representing a package exported by the current module.

At most one entry in the exports table may specify a package of a given name with its exports_index item. (Compile-time)

exports_flags

The value of the exports_flags item is as follows:

0x1000 (ACC_SYNTHETIC)

Indicates that this export was not explicitly or implicitly declared in the source of the module declaration.

0x8000 (ACC_MANDATED)

Indicates that this export was implicitly declared in the source of the module declaration.

exports_to_count

The value of the exports_to_count indicates the number of entries in the exports_to_index table.

exports_to_index

The value of each exports_to_index item must be a valid index into the constant_pool table. The constant_pool entry at that index must be a CONSTANT_Module_info structure denoting a module whose code can access the types and members in this exported package.

For each entry in the exports table, at most one entry in its exports_to_index table may specify a module of a given name. (Compile-time)

opens_count

The value of the opens_count item indicates the number of entries in the opens table.

opens_count must be zero if the current module is open. (Compile-time)

opens[]

Each entry in the opens table specifies a package opened by the current module, such that all types in the package, and all their members, may be accessed from outside the current module via the reflection libraries of the Java SE Platform, possibly from a limited set of "friend" modules.

The items in each entry are as follows:

opens_index

The value of the opens_index item must be a valid index into the constant_pool table. The constant_pool entry at that index must be a CONSTANT_Package_info structure representing a package opened by the current module.

At most one entry in the opens table may specify a package of a given name with its opens_index item. (Compile-time)

opens_flags

The value of the opens_flags item is as follows:

0x1000 (ACC_SYNTHETIC)

Indicates that this opening was not explicitly or implicitly declared in the source of the module declaration.

0x8000 (ACC_MANDATED)

Indicates that this opening was implicitly declared in the source of the module declaration.

opens_to_count

The value of the opens_to_count indicates the number of entries in the opens_to_index table.

opens_to_index

The value of each opens_to_index item must be a valid index into the constant_pool table. The constant_pool entry at that index must be a CONSTANT_Module_info structure denoting a module whose code can access the types and members in this opened package.

For each entry in the opens table, at most one entry in its opens_to_index table may specify a module of a given name. (Compile-time)

uses_count

The value of the uses_count item indicates the number of entries in the uses_index table.

uses_index[]

The value of each uses_index entry must be a valid index into the constant_pool table. The constant_pool entry at that index must be a CONSTANT_Class_info structure representing a service interface which the current module may discover via java.util.ServiceLoader.

At most one entry in the uses_index table may specify a service interface of a given name. (Compile-time)

provides_count

The value of the provides_count item indicates the number of entries in the provides table.

provides[]

Each entry in the provides table represents a service implementation for a given service interface.

The items in each entry are as follows:

provides_index

The value of the provides_index item must be a valid index into the constant_pool table. The constant_pool entry at that index must be a CONSTANT_Class_info structure representing a service interface for which the current module provides a service implementation.

At most one entry in the provides table may specify a service interface of a given name with its provides_index item. (Compile-time)

provides_with_count

The value of the provides_with_count indicates the number of entries in the provides_with_index table.

provides_with_index

The value of each provides_with_index item must be a valid index into the constant_pool table. The constant_pool entry at that index must be a CONSTANT_Class_info structure representing a service implementation for the service interface specified by provides_index.

For each entry in the provides table, at most one entry in its provides_with_index table may specify a service implementation of a given name. (Compile-time)

2.3. The ModulePackages attribute

The ModulePackages attribute is a variable-length attribute in the attributes table of a ClassFile structure. The ModulePackages attribute indicates all the packages of a module that are exported or opened by the Module attribute, as well as all the packages of the service implementations recorded in the Module attribute. The ModulePackages attribute may also indicate packages in the module that are neither exported nor opened nor contain service implementations.

There may be at most one ModulePackages attribute in the attributes table of a ClassFile structure.

ModulePackages_attribute {
    u2 attribute_name_index;
    u4 attribute_length;

    u2 package_count;
    u2 package_index[package_count];
}
attribute_name_index

The value of the attribute_name_index item must be a valid index into the constant_pool table. The constant_pool entry at that index must be a CONSTANT_Utf8_info structure representing the string "ModulePackages".

attribute_length

The value of the attribute_length item is the length of the attribute excluding the initial six bytes.

package_count

The value of the package_count item indicates the number of entries in the package_index table.

package_index[]

The value of each package_index entry must be a valid index into the constant_pool table. The constant_pool entry at that index must be a CONSTANT_Package_info structure representing a package in the current module.

At most one entry in the package_index table may specify a package of a given name.

2.4. The ModuleMainClass attribute

The ModuleMainClass attribute is a fixed-length attribute in the attributes table of a ClassFile structure. The ModuleMainClass attribute indicates the main class of a module.

There may be at most one ModuleMainClass attribute in the attributes table of a ClassFile structure.

ModuleMainClass_attribute {
    u2 attribute_name_index;
    u4 attribute_length;

    u2 main_class_index;
}
attribute_name_index

The value of the attribute_name_index item must be a valid index into the constant_pool table. The constant_pool entry at that index must be a CONSTANT_Utf8_info structure representing the string "ModuleMainClass".

attribute_length

The value of the attribute_length item is the length of the attribute excluding the initial six bytes.

main_class_index

The value of the main_class_index item must be a valid index into the constant_pool table. The constant_pool entry at that index must be a CONSTANT_Class_info structure representing the binary name of the main class of the current module.

2.5. The CONSTANT_Module_info Structure

The CONSTANT_Module_info structure is used to represent a module:

CONSTANT_Module_info {
    u1 tag;
    u2 name_index;
}

The items of the CONSTANT_Module_info structure are as follows:

tag

The tag item has the value CONSTANT_Module (19).

name_index

The value of the name_index item must be a valid index into the constant_pool table. The constant_pool entry at that index must be a CONSTANT_Utf8_info structure representing a module name.

A CONSTANT_Module_info structure is permitted only in the constant pool of a ClassFile structure that declares a module (that is, a ClassFile structure where the access_flags item has the ACC_MODULE flag set). In all other ClassFile structures, a CONSTANT_Module_info structure is illegal.

2.6. The CONSTANT_Package_info Structure

The CONSTANT_Package_info structure is used to represent a package exported or opened by a module:

CONSTANT_Package_info {
    u1 tag;
    u2 name_index;
}

The items of the CONSTANT_Package_info structure are as follows:

tag

The tag item has the value CONSTANT_Package (20).

name_index

The value of the name_index item must be a valid index into the constant_pool table. The constant_pool entry at that index must be a CONSTANT_Utf8_info structure representing a package name encoded in internal form.

A CONSTANT_Package_info structure is permitted only in the constant pool of a ClassFile structure that declares a module (that is, a ClassFile structure where the access_flags item has the ACC_MODULE flag set). In all other ClassFile structures, a CONSTANT_Package_info structure is illegal.