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.