Table of Contents
Table of Contents
module M @ 1.0 { requires A @ /* Use v2 or above */ >= 2.0 ; requires B for compilation, reflection; requires service S1; requires optional service S2; provides MI @ 4.0; provides service MS with C; exports ME; permits MF; class MMain; view N { provides NI @ 1.0; provides service NS with D; exports NE; permits MF; class NMain; } }
module
, requires
, compilation
, reflection
, execution
, service
,
local
, optional
, provides
,
with
, exports
, permits
, and
view
are restricted keywords.
This means that 'provides
service
;
' is legal - service
is interpreted as an identifier because
the token stream can be seen as not proceeding to declare a
service. Also, 'provides
service
service
with
service
;
' is
legal.
About a module declaration:
-
A compilation unit (JLS 7.3) may contain a module declaration.
In this case, the filename of the compilation unit is typically
module-info.java
. -
A module declaration indicates a module name, optionally followed by
@
and a module version. A module declaration may not be annotated. -
A module name is a qualified identifier, in the spirit of a package-or-type name and a type name (JLS 6.5).
-
A module version is a new kind of literal, starting with a digit and thereafter consisting of Java letters, Java digits,
.
characters, and-
characters in a sequence acceptable to the module system. (Requirement) -
If a module declaration does not express a dependency on the
java.base
module, and the module declaration is not ofjava.base
itself, then it is as if the module declaration has a dependency on a version of thejava.base
module chosen by the host system.
About the requires
directive:
-
requires
takes a qualified identifier indicating a module name (if the modifierservice
is not present) or a service name (if the modifierservice
is present). (Requirement, Requirement) -
A module name may be preceded by one or more of the flags
local
andpublic
.A module name may be followed by
@
and a version query. A version query is either a version, or an operator followed by a version. (Requirement)A module name (or version query) may be followed by
for
and one or more of the scopescompilation
,reflection
, andexecution
. (Requirement, Description of scopes)If no
for
clause is present, then it is as if afor
compilation
,
execution
clause was present.
About the other directives:
-
provides
takes a qualified identifier indicating a module name to serve as an alias (if the modifierservice
is not present) or a service name to be implemented (if the modifierservice
is present). (Requirement)A module name may be followed by
@
and a version.A service name must be followed by a
with
clause that indicates the implementation for the service. (Requirement) -
exports
takes a qualified identifier indicating the name of a package to be exported. (Requirement) -
permits
takes a qualified identifier indicating the name of a module which is permitted to depend on this module. (Requirement) -
class
takes a qualified identifier indicating the name of the type which is an entry point for the module or view. -
view
takes a qualified identifier indicating the name of the view, followed by a set ofprovides
,exports
,permits
, andclass
clauses defining the view as seen byrequires
clauses in other modules. -
Every module has a default view. Any
provides
,exports
,permits
, orclass
clause not declared in a named view is implicitly declared in the module's default view.
Compile-time errors concerning duplicates:
-
It is a compile-time error if more than one
requires
clause (that gives a module name) in a module declaration indicates the same module name. -
It is a compile-time error if more than one
requires
service
clause in a module declaration indicates the same service name. -
It is a compile-time error if more than one
provides
clause (that gives a module name) in a view indicates the same module name.It is a compile-time error if more than one
provides
service
clause in a view indicates the same pair of service name and implementation.(Multiple
provides
service
clauses in a view may give the same service name with different implementations.) -
It is a compile-time error if more than one
exports
clause in a view indicates the same package name. -
It is a compile-time error if more than one
permits
clause in a view indicates the same module name. -
It is a compile-time error if a module declaration contains more than one view of the same name (whether declared as a non-default view or implicit as the default view).
-
It is a compile-time error if an
exports
clause in a non-default view indicates the same package name as anexports
clause in the default view.(A non-default view inherits the
exports
clauses of the default view, so duplicates should be prohibited among the combined default/non-default exports, as well as among the non-default exports.)
Compile-time errors concerning references to other entities:
-
It is a compile-time error if an implementation named by the
with
clause ofprovides
service
isabstract
, or is notpublic
, or does not have apublic
no-args constructor, or is an inner class (JLS 8.1.3). -
A type named as an entry point must indicate a class (of any accessibility) that declares a method called
main
which ispublic
,static
,void
, and has a single formal parameter of typeString
[]
, or a compile-time error occurs. -
The operator in a version query must be
<<
,<=
,=
,>=
, or>>
, or a compile-time error occurs. -
It is a compile-time error if a
requires
clause indicates both thereflection
scope and theexecution
scope.
The grammar below uses the following BNF-style conventions:
-
[x] denotes zero or one occurrences of x.
-
{x} denotes zero or more occurrences of x.
-
(x | y) means one of either x or y.
Literal:
VersionLiteral
VersionLiteral:
JavaDigit VersionLiteralChars
VersionLiteralChars:
VersionLiteralChar
VersionLiteralChars VersionLiteralChar
VersionLiteralChar:
JavaLetterOrDigit
.
-
CompilationUnit:
[PackageDeclaration] {ImportDeclaration} {TypeDeclaration}
[ModuleDeclaration]
ModuleDeclaration:
module
ModuleNameAndVersion {
{ModuleDirective} }
ModuleNameAndVersion:
ModuleName [@
VersionLiteral]
ModuleName:
Identifier
ModuleName .
Identifier
ModuleDirective:
RequiresDirective
ProvidesDirective
ExportsDirective
PermitsDirective
EntrypointDirective
ViewDeclaration
RequiresDirective:
requires
{local
| public
} ModuleNameAndVersionQuery [for
ScopeList] ;
requires
[optional
] service
ServiceName ;
ModuleNameAndVersionQuery:
ModuleName [@
VersionQuery]
VersionQuery:
[Operator] VersionLiteral
ScopeList:
Scope
ScopeList ,
Scope
Scope:
compilation
reflection
execution
ServiceName:
Identifier
ServiceName .
Identifier
ProvidesDirective:
provides
ModuleNameAndVersion ;
provides
service
ServiceName with
QualifiedIdentifier ;
ExportsDirective:
exports
PackageName ;
PermitsDirective:
permits
ModuleName ;
EntrypointDirective:
class
TypeName ;
ViewDeclaration:
view
ModuleName {
{ProvidesDirective | ExportsDirective | PermitsDirective | EntrypointDirective}
}
Table of Contents
A compilation unit that contains a module declaration (and
potentially additional arbitrary content) is compiled to a
ClassFile
structure like any other
compilation unit.
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. This
flag plays a similar role to ACC_ANNOTATION
(0x2000) and ACC_ENUM
(0x4000) in flagging this ClassFile
as "not a normal class", and 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-infoTraditionally, if
this_class
indicates "P/Q/R", then theClassFile
can be expected to live in a fileR.class
in a directoryP/Q
representing a package. This explains why "/module-info" is a suffix inthis_class
above: ifthis_class
indicates "P/Q/module-info", then theClassFile
can be expected to live in a filemodule-info.class
in a directoryP/Q
representing a module. The "real name" of the module, shorn of "/module-info", can be obtained from theModule
attribute. -
super_class
,interfaces_count
,fields_count
,methods_count
: zero -
attributes
: OneModule
attribute must be present, to record the name and version of the module. At most one of each of theModuleRequires
,ModuleProvides
, andModuleData
attributes may be present. Except for these attributes andSynthetic
,SourceFile
,SourceDebugExtension
, andDeprecated
, none of the pre-defined attributes in JVMS 4.7 may appear.
Some notes on compilation:
-
There are no implicit
requires
dependences at theClassFile
level. That is, if noModuleRequires.modules
table is physically present, then no such table is inferred by the Java virtual machine.There will, however, always be a
ModuleRequires.modules
table in aClassFile
, due to the universal dependence of all modules onjava.base
. (Compile-time) TheACC_SYNTHESIZED
flag is available for a compiler to record that a module declaration in source did not have an explicitrequires
clause forjava.base
. -
There are no implicit re-exports (
requires
public
) at theClassFile
level. That is, theACC_REEXPORT
flag is not set by default inModuleRequires.modules
. -
There are no implicit scopes for module dependencies at the
ClassFile
level. That is, a compiler must explicitly set a module dependency's scope inModuleRequires.modules.module_flags
if a target module is required in that scope. -
There are no implicit exports from views at the
ClassFile
level. That is, if noModuleProvides.exports
table is physically present, then no such table is inferred by the Java virtual machine. -
An empty
ModuleProvides.permits
table means all other modules are permitted. -
If a module declaration contains a default view, the default view's permits and exports are explicitly copied into the
module-info.class
file for all non-default views.module-info.class
contains explicit permits and exports, with the exception of an empty permits table which implies permits all.
Module_attribute { u2 attribute_name_index; u4 attribute_length; u2 module_id_index; }
The items of the Module_attribute
structure are as follows:
- attribute_name_index
-
The value of the
attribute_name_index
item must be a valid index into theconstant_pool
table. Theconstant_pool
entry at that index must be aCONSTANT_Utf8_info
structure representing the string "Module". - attribute_length
-
The value of the
attribute_length
item must be 2. - module_id_index
-
The value of the
module_id_index
item must be a valid index into theconstant_pool
table. Theconstant_pool
entry at that index must be aCONSTANT_ModuleId_info
structure (§2.6) representing the name and version of the module represented by thisClassFile
.The name must be equal to the module name indicated by the
ClassFile.this_class
item without the "/module-info" suffix.
ModuleRequires_attribute { u2 attribute_name_index; u4 attribute_length; u2 modules_count; { u2 module_index; u4 module_flags; } modules[modules_count]; u2 services_count; { u2 service_index; u4 service_flags; } services[service_count]; }
- attribute_name_index
-
The value of the
attribute_name_index
item must be a valid index into theconstant_pool
table. Theconstant_pool
entry at that index must be aCONSTANT_Utf8_info
structure representing the string "ModuleRequires". - attribute_length
-
The value of the
attribute_length
item is the length of the attribute excluding the initial six bytes. - modules_count
-
The value of the
modules_count
item indicates the number of entries in themodules
table. - modules
-
The value of each
module_index
entry must be a valid index into theconstant_pool
table. Theconstant_pool
entry at that index must be aCONSTANT_ModuleQuery_info
structure (§2.7) representing a query for a target module on which the module represented by thisClassFile
depends. (Compile-time)A target module name may be referenced by at most one entry in a
modules
table. (Compile-time)Unless the
ClassFile
represents the modulejava.base
, exactly one entry in amodules
table must indicate a target module whose name isjava.base
, and its associatedmodule_flags
item must haveACC_COMPILATION_SCOPE
andACC_EXECUTION_SCOPE
set and not haveACC_REFLECTION_SCOPE
orACC_SYNTHETIC
set. (Compile-time)The value of the associated
module_flags
item is as follows:- 0x0001 (
ACC_COMPILATION_SCOPE
) -
Indicates that the target module must be present at compile-time. (Compile-time)
- 0x0002 (
ACC_REFLECTION_SCOPE
) -
Indicates that the target module may be present at run-time. (Compile-time)
- 0x0004 (
ACC_EXECUTION_SCOPE
) -
Indicates that the target module must be present at run-time. (Compile-time)
- 0x0010 (
ACC_LOCAL
) -
Indicates that the target module's types must be loaded by the same defining classloader as the types of the module represented by this
ClassFile
. (Requirement, Compile-time) - 0x0020 (
ACC_REEXPORT
) -
Indicates that the module re-exports the visible types which are exported by the target module. (Compile-time)
- 0x1000 (
ACC_SYNTHETIC
) -
Indicates the dependency is synthetic.
- 0x10000 (
ACC_SYNTHESIZED
) -
Indicates the dependency is synthesized.
In a
module_flags
item, at most one of theACC_REFLECTION_SCOPE
andACC_EXECUTION_SCOPE
flags must be set. (Compile-time) - 0x0001 (
- services_count
-
The value of the
services_count
item indicates the number of entries in theservices
table. - services
-
The value of each
services
entry must be a valid index into theconstant_pool
table. Theconstant_pool
entry at that index must be aCONSTANT_Class_info
structure representing a service (interface or abstract class) on which the module represented by thisClassFile
depends. (Requirement)A service may be referenced by at most one entry in a
services
table. (Compile-time)The value of the associated
service_flags
item is as follows:- 0x0001 (
ACC_OPTIONAL
) -
Indicates that this dependency on a service is optional at run-time. (Compile-time)
- 0x1000 (
ACC_SYNTHETIC
) -
Indicates the dependency is synthetic.
- 0x10000 (
ACC_SYNTHESIZED
) -
Indicates the dependency is synthesized.
- 0x0001 (
The range of entities offered by a module to the outside world
has grown over time. It started off as aliases (provides
) and friends (permits
), then added entry points (class
) and packages (exports
). Recently, services (provides service
) were added. Individual
attributes for each kind of entity (ModuleProvides
, ModulePermits
, ModuleEntrypoint
, ModuleExports
) add little value. The introduction
of "views" into the module system - where a view aggregates
entities offered by a module, and where a module always has at
least one "default" view - suggests a simple ClassFile
representation: one attribute defines
all views and the entities they offer. This authoritative
description of what a module offers is a natural counterpart to the
ModuleRequires
attribute that
describes what a module needs.
ModuleProvides_attribute { u2 attribute_name_index; u4 attribute_length; u2 views_count; { u2 view_name_index; u2 entrypoint_index; u2 aliases_count; { u2 alias_index; } aliases[aliases_count]; u2 services_count; { u2 service_index; u2 impl_index; } services[services_count]; u2 exports_count; { u2 export_index; } exports[exports_count]; u2 permits_count; { u2 permit_index; } permits[permit_count]; } views[views_count]; }
- attribute_name_index
-
The value of the
attribute_name_index
item must be a valid index into theconstant_pool
table. Theconstant_pool
entry at that index must be aCONSTANT_Utf8_info
structure representing the string "ModuleProvides". - attribute_length
-
The value of the
attribute_length
item is the length of the attribute excluding the initial six bytes. - views_count
-
The value of the
views_count
item indicates the number of entries in theviews
table. - views
-
Each entry in the
views
table has the following entries:- view_name_index
-
The value of the
view_name_index
item must either be zero (to indicate this is the default view for the module represented by thisClassFile
; the view's name is that of the module), or a valid index into theconstant_pool
table. Theconstant_pool
entry at that index must be aCONSTANT_Utf8_info
structure representing the view's name in internal form (JVMS 4.2.1).Within the
views
table, the name of each view (whether a default view or a non-default view) must be unique. (Compile-time) - entrypoint_index
-
The value of the
entrypoint_index
item must either be zero (to indicate this view has no entrypoint) or a valid index into theconstant_pool
table. Theconstant_pool
entry at that index must be aCONSTANT_Class_info
structure representing the name of the class in internal form (JVMS 4.2.1) which is the entrypoint to this view. - aliases_count
-
The value of the
aliases_count
item indicates the number of entries in thealiases
table. - aliases
-
The value of each
aliases
entry must be a valid index into theconstant_pool
table. Theconstant_pool
entry at that index must be aCONSTANT_ModuleId_info
structure (§2.6) representing a module name that is an alias for the module represented by this view. (Compile-time)Within an entry of the
views
table, an alias's module name may be referenced by at most one entry in thealiases
table. (Compile-time) - services_count
-
The value of the
services_count
item indicates the number of entries in theservices
table. - services
-
The value of each
service_index
item must be a valid index into theconstant_pool
table. Theconstant_pool
entry at that index must be aCONSTANT_Class_info
structure representing a service (interface or abstract class) provided by this view.The value of the associated
impl_index
item in this table must be a valid index into theconstant_pool
table. Theconstant_pool
entry at that index must be aCONSTANT_Class_info
structure representing the implementation for the service atservice_index
.Within an entry of the
views
table, at most one entry in theservices
table may reference the same pair ofservice_index
andimpl_index
values. (Compile-time) - exports_count
-
The value of the
exports_count
item indicates the number of entries in theexports
table. - exports
-
The value of each
export_index
item must be a valid index into theconstant_pool
table. Theconstant_pool
entry at that index must be aCONSTANT_Utf8_info
structure representing the name in internal form (JVMS 4.2.1) of a package to be exported by this view. (Compile-time)Within an entry of the
views
table, a package name may be referenced by at most one entry in theexports
table. (Compile-time) - permits_count
-
The value of the
permits_count
item indicates the number of entries in thepermits
table. - permits
-
The value of each
permit_index
item must be a valid index into theconstant_pool
table. Theconstant_pool
entry at that index must be aCONSTANT_ModuleId_info
structure (§2.6) representing a module which is permitted to have a dependency on the current view. (Compile-time)It is possible that a module system uses only the name of the permitted module, not its version, in determining visibility.
Within an entry of the
views
table, a module name may be referenced by at most one entry in thepermits
table. (Compile-time)
ModuleData_attribute { u2 attribute_name_index; u4 attribute_length; u2 data_index; }
- attribute_name_index
-
The value of the
attribute_name_index
item must be a valid index into theconstant_pool
table. Theconstant_pool
entry at that index must be aCONSTANT_Utf8_info
structure representing the string "ModuleData". - attribute_length
-
The value of the
attribute_length
item is 2. - data_index
-
The value of the
data_index
item must be a valid index into theconstant_pool
table. Theconstant_pool
entry at that index must be aCONSTANT_Utf8_info
structure representing the textual content, other than the module declaration, of the compilation unit that declared the module represented by thisClassFile
.
The CONSTANT_ModuleId_info
structure in the constant pool is used to represent a pair of a
module name and a version.
CONSTANT_ModuleId_info { u1 tag; u2 name_index; u2 version_index; }
- tag
-
The
tag
item has the valueCONSTANT_ModuleId
(19). - name_index
-
The value of the
name_index
item must be a valid index into theconstant_pool
table. Theconstant_pool
entry at that index must be aCONSTANT_Utf8_info
structure representing the module name in internal form (JVMS 4.2.1). - version_index
-
If the value of the
version_index
item is not zero, then a version is present. The value must be a valid index into theconstant_pool
table. Theconstant_pool
entry at that index must be aCONSTANT_Utf8_info
structure representing a version acceptable to the module system. (Note that there is a standard version format which must be followed or else aClassFormatError
will be thrown. It is simply that the format is not defined by The Java™ Virtual Machine Specification.)If the value of the
version_index
item is zero (as opposed to pointing to aCONSTANT_Utf8_info
structure which holds the string "0"), then no version is present.
The CONSTANT_ModuleQuery_info
structure in the constant pool is used to represent a pair of a
module name and a version query.
CONSTANT_ModuleQuery_info { u1 tag; u2 name_index; u2 versionquery_index; }
- tag
-
The
tag
item has the valueCONSTANT_ModuleQuery
(20). - name_index
-
The value of the
name_index
item must be a valid index into theconstant_pool
table. Theconstant_pool
entry at that index must be aCONSTANT_Utf8_info
structure representing the module name in internal form (JVMS 4.2.1). - versionquery_index
-
If the value of the
versionquery_index
item is not zero, then a version query is present. The value must be a valid index into theconstant_pool
table. Theconstant_pool
entry at that index must be aCONSTANT_Utf8_info
structure representing a version query acceptable to the module system.If the value of the
versionquery_index
item is zero (as opposed to pointing to aCONSTANT_Utf8_info
structure which holds the string "0"), then no version query is present.