Table of Contents
Table of Contents
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}
ModuleDeclaration
ModuleDeclaration:
module ModuleName { {ModuleStatement} }
ModuleName:
Identifier
ModuleName . Identifier
ModuleStatement:
requires [public] ModuleName ;
exports PackageName [to ModuleName {, ModuleName}] ;
uses TypeName ;
provides TypeName with TypeName ;
Example:
module M.N {
requires A.B;
requires public C.D;
exports P.Q;
exports R.S to T1.U1, T2.U2;
uses V.W;
provides X.Y with Z1.Z2;
provides X.Y with Z3.Z4;
}
module, requires, exports, 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 is a qualified identifier, in the spirit of a package name or type name (JLS 6.5). 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 module declaration may not be annotated.
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 indicates 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 public. This causes any module which depends on the
current module to have an implicitly declared dependence on the module
specified by the requires public 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 exports statement takes a
qualified identifier indicating the name of a package to be exported
from the current module. This makes public types in the package be
accessible to code in other
modules. (Requirement)
If an exports statement has a to
clause, then the package's public types are accessible only to code
in the modules specified in the to
clause. (Requirement)
It is a compile-time error if the named package is not observable in the current module.
If the named package 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 a compile-time error if more
than one exports statement in a module declaration indicates the
same package name.
It is a compile-time error if the to
clause of an exports statement indicates a module which is not
observable.
It is a compile-time error if the to
clause of an exports statement indicates the same module name more
than once.
The uses statement takes a qualified
identifier indicating the name of a type which is a service
interface. (Requirement)
The service interface being used 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 the current module, or a compile-time error occurs.
It is a compile-time error if more
than one uses statement in a module declaration indicates the same
type name.
The provides statement takes a
qualified identifier indicating the name of a type which is a service
interface, then the with clause indicates the name of a type which
is the service implementation.
(Requirement)
The service interface being implemented 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 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.
It is a compile-time error if the
service implementation is abstract, or is not public, or does not
have a public no-args constructor, or is an inner class (JLS
8.1.3).
It is a compile-time error if more
than one provides statement in a module declaration indicates the
same pair of service interface and service implementation.
Table of Contents
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. The ACC_MODULE
flag plays a similar role to ACC_ANNOTATION (0x2000) and ACC_ENUM
(0x4000) in denoting this ClassFile as "not a normal
class". The ACC_MODULE flag
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's name in internal
form (JVMS 4.2.1)]/module-info
Traditionally, if this_class
indicates P/Q/R, then the ClassFile
occupies a file R.class in a directory
representing the package P.Q. Similarly,
if this_class
indicates P/Q/module-info, then the
ClassFile occupies a file module-info.class
in a directory representing the
module P.Q.
super_class, interfaces_count,
fields_count, methods_count:
zero
attributes: One Module attribute must
be present. Except for Module, ConcealedPackages, Version,
MainClass, TargetPlatform, InnerClasses, Synthetic,
SourceFile, SourceDebugExtension, and Deprecated, none of
the pre-defined attributes in JVMS 4.7 may appear.
The Module attribute is generally explicit about the module's
requirements, permissions, exports, and services:
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 the existence of any
particular entry therein.
Unless the current module is java.base, the Module
attribute will have a requires table of at
least length one, because every module (except java.base)
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)
There are no implicit exports statements at the
ClassFile level. If the exports_count item
is zero, then the Java Virtual Machine does not infer the existence of
an exports table nor the existence of any
particular entry therein.
Similarly for the uses and provides statements.
There is, however, one place where no information implies something meaningful:
In an entry of the exports table, if
the exports_to_count item is zero and thus
the exports_to_index table is empty, then the
Java Virtual Machine allows code in all modules to access
the public types of the exported package.
The Module attribute is a variable-length attribute in the
attributes table of a ClassFile structure. The Module attribute
indicates the requirements, permissions, 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 requires_count;
{ u2 requires_index;
u2 requires_flags;
} requires[requires_count];
u2 exports_count;
{ u2 exports_index;
u2 exports_to_count;
u2 exports_to_index[exports_to_count];
} exports[exports_count];
u2 uses_count;
u2 uses_index[uses_count];
u2 provides_count;
{ u2 provides_index;
u2 with_index;
} provides[provides_count];
}
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".
The value of the attribute_length item
is the length of the attribute excluding the initial six
bytes.
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)
Each entry in the requires table
represents a dependence of the current
module. (Compile-time)
The items in each entry are as follows:
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_Utf8_info structure representing the name of
a module on which the current module depends.
The value of the requires_flags
item is as follows:
ACC_PUBLIC)Indicates that the current module causes any module which depends on it to implicitly declare a dependence on the module indicated by this entry. (Compile-time)
ACC_SYNTHETIC)Indicates that the dependence was not explicitly or implicitly declared in the source of the module declaration.
ACC_MANDATED)Indicates the dependence was implicitly declared in the source of the module declaration.
A module name may be referenced by at most one entry in
the requires table.
(Compile-time)
Unless the current module is java.base, exactly one entry
in the requires table must have
a requires_index item indicating java.base
and a requires_flags item with the
ACC_SYNTHETIC flag not set.
(Compile-time)
The value of the exports_count
item indicates the number of entries in
the exports table.
Each entry in the exports table
represents an exported package of the current
module. (Compile-time)
The items in each entry are as follows:
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_Utf8_info structure representing the name in
internal form (JVMS 4.2.1) of a package to be exported
by the current module.
A package name may be referenced by at most one entry in
the exports
table. (Compile-time)
The value of the exports_to_count
indicates the number of entries in
the exports_to_index table.
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_Utf8_info structure representing the name in
internal form of a module whose code can access the
public types in this package.
(Compile-time)
A module name may be referenced by at most one entry in
the exports_to_index
table. (Compile-time)
The value of the uses_count item
indicates the number of entries in
the uses_index table.
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 or abstract class) on which the module
represented by this ClassFile
depends. (Compile-time)
A service may be referenced by at most one entry in
a uses_index
table. (Compile-time)
The value of the provides_count item
indicates the number of entries in
the provides table.
Each entry in the provides table
represents an implementation of a given
service. (Compile-time)
The items in each entry are as follows:
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 or abstract class) provided by the current
module.
The value of the 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 the
implementation for the service
at provides_index.
At most one entry in the provides table
may reference the same pair of provides_index
and with_index values.
(Compile-time)
The ConcealedPackages attribute is a variable-length attribute
in the attributes table of a ClassFile structure. The
ConcealedPackages attribute indicates the non-exported packages of a
module.
There may be at most one ConcealedPackages attribute in the
attributes table of a ClassFile structure.
ConcealedPackages_attribute {
u2 attribute_name_index;
u4 attribute_length;
u2 packages_count;
{ u2 package_index;
} packages[package_count];
}
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
"ConcealedPackages".
The value of the attribute_length item
is the length of the attribute excluding the initial six
bytes.
The value of the packages_count item
indicates the number of entries in
the packages table.
Each entry in the packages table
indicates the name of a concealed package. The items in each
entry are as follows:
The value of the package_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 name in
internal form of a package in the current module that is
not to be exported.
A package name may be referenced by at most one entry in
the packages table.
The Version attribute is a fixed-length attribute in the
attributes table of a ClassFile structure. The Version attribute
indicates the version of a module.
There may be at most one Version attribute in the attributes
table of a ClassFile structure.
Version_attribute {
u2 attribute_name_index;
u4 attribute_length;
u2 version_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
"Version".
The value of the attribute_length item
is the length of the attribute excluding the initial six
bytes.
The value of the 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.
The MainClass attribute is a fixed-length attribute in the
attributes table of a ClassFile structure. The MainClass
attribute indicates the fully qualified name of the main class of a
module.
There may be at most one MainClass attribute in the
attributes table of a ClassFile structure.
MainClass_attribute {
u2 attribute_name_index;
u4 attribute_length;
u2 main_class_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
"MainClass".
The value of the attribute_length item
is the length of the attribute excluding the initial six
bytes.
The value of the version_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 main class of
the current module.
The TargetPlatform attribute is a fixed-length attribute in
the attributes table of a ClassFile structure. The
TargetPlatform attribute indicates the operating system required by
a module.
There may be at most one TargetPlatform attribute in the
attributes table of a ClassFile structure.
TargetPlatform_attribute {
u2 attribute_name_index;
u4 attribute_length;
u2 os_name_index;
u2 os_arch_index;
u2 os_version_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
"TargetPlatform".
The value of the attribute_length item
is the length of the attribute excluding the initial six
bytes.
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.