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.basemodule, and the module declaration is not ofjava.baseitself, then it is as if the module declaration has a dependency on a version of thejava.basemodule chosen by the host system.
About the requires directive:
-
requirestakes a qualified identifier indicating a module name (if the modifierserviceis not present) or a service name (if the modifierserviceis present). (Requirement, Requirement) -
A module name may be preceded by one or more of the flags
localandpublic.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
forand one or more of the scopescompilation,reflection, andexecution. (Requirement, Description of scopes)If no
forclause is present, then it is as if aforcompilation,executionclause was present.
About the other directives:
-
providestakes a qualified identifier indicating a module name to serve as an alias (if the modifierserviceis not present) or a service name to be implemented (if the modifierserviceis present). (Requirement)A module name may be followed by
@and a version.A service name must be followed by a
withclause that indicates the implementation for the service. (Requirement) -
exportstakes a qualified identifier indicating the name of a package to be exported. (Requirement) -
permitstakes a qualified identifier indicating the name of a module which is permitted to depend on this module. (Requirement) -
classtakes a qualified identifier indicating the name of the type which is an entry point for the module or view. -
viewtakes a qualified identifier indicating the name of the view, followed by a set ofprovides,exports,permits, andclassclauses defining the view as seen byrequiresclauses in other modules. -
Every module has a default view. Any
provides,exports,permits, orclassclause 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
requiresclause (that gives a module name) in a module declaration indicates the same module name. -
It is a compile-time error if more than one
requiresserviceclause in a module declaration indicates the same service name. -
It is a compile-time error if more than one
providesclause (that gives a module name) in a view indicates the same module name.It is a compile-time error if more than one
providesserviceclause in a view indicates the same pair of service name and implementation.(Multiple
providesserviceclauses in a view may give the same service name with different implementations.) -
It is a compile-time error if more than one
exportsclause in a view indicates the same package name. -
It is a compile-time error if more than one
permitsclause 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
exportsclause in a non-default view indicates the same package name as anexportsclause in the default view.(A non-default view inherits the
exportsclauses 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
withclause ofprovidesserviceisabstract, or is notpublic, or does not have apublicno-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
mainwhich 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
requiresclause indicates both thereflectionscope and theexecutionscope.
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_classindicates "P/Q/R", then theClassFilecan be expected to live in a fileR.classin a directoryP/Qrepresenting a package. This explains why "/module-info" is a suffix inthis_classabove: ifthis_classindicates "P/Q/module-info", then theClassFilecan be expected to live in a filemodule-info.classin a directoryP/Qrepresenting a module. The "real name" of the module, shorn of "/module-info", can be obtained from theModuleattribute. -
super_class,interfaces_count,fields_count,methods_count: zero -
attributes: OneModuleattribute must be present, to record the name and version of the module. At most one of each of theModuleRequires,ModuleProvides, andModuleDataattributes 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
requiresdependences at theClassFilelevel. That is, if noModuleRequires.modulestable is physically present, then no such table is inferred by the Java virtual machine.There will, however, always be a
ModuleRequires.modulestable in aClassFile, due to the universal dependence of all modules onjava.base. (Compile-time) TheACC_SYNTHESIZEDflag is available for a compiler to record that a module declaration in source did not have an explicitrequiresclause forjava.base. -
There are no implicit re-exports (
requirespublic) at theClassFilelevel. That is, theACC_REEXPORTflag is not set by default inModuleRequires.modules. -
There are no implicit scopes for module dependencies at the
ClassFilelevel. That is, a compiler must explicitly set a module dependency's scope inModuleRequires.modules.module_flagsif a target module is required in that scope. -
There are no implicit exports from views at the
ClassFilelevel. That is, if noModuleProvides.exportstable is physically present, then no such table is inferred by the Java virtual machine. -
An empty
ModuleProvides.permitstable 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.classfile for all non-default views.module-info.classcontains 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_indexitem must be a valid index into theconstant_pooltable. Theconstant_poolentry at that index must be aCONSTANT_Utf8_infostructure representing the string "Module". - attribute_length
-
The value of the
attribute_lengthitem must be 2. - module_id_index
-
The value of the
module_id_indexitem must be a valid index into theconstant_pooltable. Theconstant_poolentry at that index must be aCONSTANT_ModuleId_infostructure (§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_classitem 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_indexitem must be a valid index into theconstant_pooltable. Theconstant_poolentry at that index must be aCONSTANT_Utf8_infostructure representing the string "ModuleRequires". - attribute_length
-
The value of the
attribute_lengthitem is the length of the attribute excluding the initial six bytes. - modules_count
-
The value of the
modules_countitem indicates the number of entries in themodulestable. - modules
-
The value of each
module_indexentry must be a valid index into theconstant_pooltable. Theconstant_poolentry at that index must be aCONSTANT_ModuleQuery_infostructure (§2.7) representing a query for a target module on which the module represented by thisClassFiledepends. (Compile-time)A target module name may be referenced by at most one entry in a
modulestable. (Compile-time)Unless the
ClassFilerepresents the modulejava.base, exactly one entry in amodulestable must indicate a target module whose name isjava.base, and its associatedmodule_flagsitem must haveACC_COMPILATION_SCOPEandACC_EXECUTION_SCOPEset and not haveACC_REFLECTION_SCOPEorACC_SYNTHETICset. (Compile-time)The value of the associated
module_flagsitem 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_flagsitem, at most one of theACC_REFLECTION_SCOPEandACC_EXECUTION_SCOPEflags must be set. (Compile-time) - 0x0001 (
- services_count
-
The value of the
services_countitem indicates the number of entries in theservicestable. - services
-
The value of each
servicesentry must be a valid index into theconstant_pooltable. Theconstant_poolentry at that index must be aCONSTANT_Class_infostructure representing a service (interface or abstract class) on which the module represented by thisClassFiledepends. (Requirement)A service may be referenced by at most one entry in a
servicestable. (Compile-time)The value of the associated
service_flagsitem 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_indexitem must be a valid index into theconstant_pooltable. Theconstant_poolentry at that index must be aCONSTANT_Utf8_infostructure representing the string "ModuleProvides". - attribute_length
-
The value of the
attribute_lengthitem is the length of the attribute excluding the initial six bytes. - views_count
-
The value of the
views_countitem indicates the number of entries in theviewstable. - views
-
Each entry in the
viewstable has the following entries:- view_name_index
-
The value of the
view_name_indexitem 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_pooltable. Theconstant_poolentry at that index must be aCONSTANT_Utf8_infostructure representing the view's name in internal form (JVMS 4.2.1).Within the
viewstable, 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_indexitem must either be zero (to indicate this view has no entrypoint) or a valid index into theconstant_pooltable. Theconstant_poolentry at that index must be aCONSTANT_Class_infostructure 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_countitem indicates the number of entries in thealiasestable. - aliases
-
The value of each
aliasesentry must be a valid index into theconstant_pooltable. Theconstant_poolentry at that index must be aCONSTANT_ModuleId_infostructure (§2.6) representing a module name that is an alias for the module represented by this view. (Compile-time)Within an entry of the
viewstable, an alias's module name may be referenced by at most one entry in thealiasestable. (Compile-time) - services_count
-
The value of the
services_countitem indicates the number of entries in theservicestable. - services
-
The value of each
service_indexitem must be a valid index into theconstant_pooltable. Theconstant_poolentry at that index must be aCONSTANT_Class_infostructure representing a service (interface or abstract class) provided by this view.The value of the associated
impl_indexitem in this table must be a valid index into theconstant_pooltable. Theconstant_poolentry at that index must be aCONSTANT_Class_infostructure representing the implementation for the service atservice_index.Within an entry of the
viewstable, at most one entry in theservicestable may reference the same pair ofservice_indexandimpl_indexvalues. (Compile-time) - exports_count
-
The value of the
exports_countitem indicates the number of entries in theexportstable. - exports
-
The value of each
export_indexitem must be a valid index into theconstant_pooltable. Theconstant_poolentry at that index must be aCONSTANT_Utf8_infostructure 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
viewstable, a package name may be referenced by at most one entry in theexportstable. (Compile-time) - permits_count
-
The value of the
permits_countitem indicates the number of entries in thepermitstable. - permits
-
The value of each
permit_indexitem must be a valid index into theconstant_pooltable. Theconstant_poolentry at that index must be aCONSTANT_ModuleId_infostructure (§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
viewstable, a module name may be referenced by at most one entry in thepermitstable. (Compile-time)
ModuleData_attribute {
u2 attribute_name_index;
u4 attribute_length;
u2 data_index;
}
- attribute_name_index
-
The value of the
attribute_name_indexitem must be a valid index into theconstant_pooltable. Theconstant_poolentry at that index must be aCONSTANT_Utf8_infostructure representing the string "ModuleData". - attribute_length
-
The value of the
attribute_lengthitem is 2. - data_index
-
The value of the
data_indexitem must be a valid index into theconstant_pooltable. Theconstant_poolentry at that index must be aCONSTANT_Utf8_infostructure 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
tagitem has the valueCONSTANT_ModuleId(19). - name_index
-
The value of the
name_indexitem must be a valid index into theconstant_pooltable. Theconstant_poolentry at that index must be aCONSTANT_Utf8_infostructure representing the module name in internal form (JVMS 4.2.1). - version_index
-
If the value of the
version_indexitem is not zero, then a version is present. The value must be a valid index into theconstant_pooltable. Theconstant_poolentry at that index must be aCONSTANT_Utf8_infostructure representing a version acceptable to the module system. (Note that there is a standard version format which must be followed or else aClassFormatErrorwill be thrown. It is simply that the format is not defined by The Java™ Virtual Machine Specification.)If the value of the
version_indexitem is zero (as opposed to pointing to aCONSTANT_Utf8_infostructure 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
tagitem has the valueCONSTANT_ModuleQuery(20). - name_index
-
The value of the
name_indexitem must be a valid index into theconstant_pooltable. Theconstant_poolentry at that index must be aCONSTANT_Utf8_infostructure representing the module name in internal form (JVMS 4.2.1). - versionquery_index
-
If the value of the
versionquery_indexitem is not zero, then a version query is present. The value must be a valid index into theconstant_pooltable. Theconstant_poolentry at that index must be aCONSTANT_Utf8_infostructure representing a version query acceptable to the module system.If the value of the
versionquery_indexitem is zero (as opposed to pointing to aCONSTANT_Utf8_infostructure which holds the string "0"), then no version query is present.