Package Summary  Overview Summary

Modules in the Java Language and JVM


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 ModuleVersionModuleMainClass attribute
2.5. The ModuleMainClassModuleTarget attribute
2.6. The CONSTANT_Module_info Structure
2.7. The ModuleTarget attributeCONSTANT_Package_info Structure

Chapter 1. Modules in the Java Language

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 isconsists of one or more Java identifiers (JLS 3.8) separated by "." tokens. In the declaration of a qualified identifier,module name (after module) and in the spiritany use of a packagemodule name (by requires, exports, or typeopens ), every identifier in the name (JLS 6.5)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.

An open module grants access at compile time and run time to types in only those packages which are explicitly exported, but grants reflective access to types in all its packages.

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, and grants reflective access to types in only those packages which are explicitly opened.

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 requirestransitive 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 from 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 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 namedpackage specified by exports is not observable in the current module.

If the namedpackage specified by exports is observable in the current module, then at least one compilation unit containing a declaration of the package must be observable in the current module, or a compile-time error occurs.

It is permitted for opens to specify a package which is not observable in the current module. (If the package should happen to be observable in 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 types and members which are exported/opened by the package are accessible solely to code in the modules specified in the to clause. For an unqualified statement, the types and members which are exported/opened by the package 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 possible service implementation 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.

The 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.

The 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 the 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 the service implementation has a publicstatic method called provider with no formal parameters, then that method is called the provider method .

If the 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 the service implementation specified by a provides statement must be declared in the current module, its provider method may return a type declared in another module.

If the service implementation does not have a provider method, then the 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

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 represents 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, ModuleVersion, ModuleMainClass, ModuleTarget, InnerClasses, SourceFile, SourceDebugExtension, Deprecated, 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. 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 entries in the constant pool. Such entries 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_Utf8Module_info structure . It representsdenoting the name in internal form (JVMS 4.2.1) of thecurrent 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 a valid index into the constant_pool table. 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_Utf8Module_info structure . It represents the name in internal form (JVMS 4.2.1) ofdenoting 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.

A module name mayrequires_version_index

The value of the requires_version_index item must be referenced bya valid index into the constant_pool table. The constant_pool entry at most one entry inthat index must be a CONSTANT_Utf8_info structure representing the version of the module specified by requires table. (Compile-time)_index .

Unless the current module is java.base, exactly one entry in the requires table must have both a requires_index item indicatingwhich indicates java.base and a requires_flags item withwhich 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_Utf8Package_info structure . It represents the name in internal form (JVMS 4.2.1) ofrepresenting a package exported by the current module.

A package name may be referenced by atAt 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_Utf8Module_info structure . It represents the name in internal form (JVMS 4.2.1) ofdenoting a module whose code can access the types and members in this exported package.

A module name may be referenced byFor each entry in the exports table, at most one entry in theits 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_Utf8Package_info structure . It represents the name in internal form (JVMS 4.2.1) ofrepresenting a package opened by the current module.

A package name may be referenced by atAt 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_Utf8Module_info structure . It represents the name in internal form (JVMS 4.2.1) ofdenoting a module whose code can access the types and members in this opened package.

A module name may be referenced byFor each entry in the opens table, at most one entry in theits 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 . It representsrepresenting a service interface which the current module may discover via java.util.ServiceLoader.

A service interface may be referenced by atAt 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 . It representsrepresenting a service interface for which the current module provides a service implementation.

A service interface may be referenced by atAt 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 . It representsrepresenting a service implementation for the service interface atspecified by provides_index.

A service implementation may be referenced byFor each entry in the provides table, at most one entry in theits 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 packagespackage_count;
    {u2 package_index;}packages[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.

packagespackage_count

The value of the packagespackage_count item indicates the number of entries in the packagespackage_index table.

packages[]

Each entry in the packages table indicates a package in the current module. The items in each entry are as follows:

package_index[]

The value of theeach package_index itementry must be a valid index into the constant_pool table. The constant_pool entry at that index must be a CONSTANT_Utf8Package_info structure representing the name in internal form (JVMS 4.2.1) ofa package in the current module.

A package name may be referenced by atAt most one entry in the packages table.

2.4. The ModuleVersion attribute

The ModuleVersion attribute is a fixed-length attribute in the attributes table of a ClassFile structure. The ModuleVersion attribute indicates the version of a module.

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

ModuleVersion_attribute{u2attribute_namepackage_index
;u4attribute_length;u2version_index;}
attribute_name_index
The value of the attribute_name_index item must be a valid index into the constant_pooltable . The constant_pool entry at that index must bemay specify a CONSTANT_Utf8_info structure representing the string "ModuleVersion".
attribute_length
The valuepackage of the attribute_length item is the length of the attribute excluding the initial six bytes.
version_index
The value of the version_index item must bea valid index into the constant_pool table. The constant_pool entry at that index must be a CONSTANT_Utf8_info structure representing the version of the current modulegiven name.

2.54. 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.65. The ModuleTarget attribute

The ModuleTarget attribute is a fixed-length attribute in the attributes table of a ClassFile structure. The ModuleTarget attribute indicates the operating system required by a module.

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

ModuleTarget_attribute {
    u2 attribute_name_index;
    u4 attribute_length;

    u2 os_name_index;
    u2 os_arch_index;
    u2 os_version_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 "ModuleTarget".

attribute_length

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

os_name_index, os_arch_index, os_version_index

The value of each of the os_name_index, os_arch_index, and os_version_index items must be either zero or a valid index into the constant_pool table. If the value of an item is zero, then no information is present for that item. If the value of an item is nonzero, then the constant_pool entry at that index must be a CONSTANT_Utf8_info structure representing the operating system name, architecture, or version (as appropriate for the item) that is required by the current module.

2.6. 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.

2.7. 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.