Project Jigsaw: Classfile changes in v51.0 for Modules

2009/2/3

Access flags

Module-private accessibility is expressed with a new access_flags flag, ACC_MODULE, value 0x8000, description: "Declared module; may not be accessed from outside its module. May only be set if the ClassFile has a Module attribute." The flag appears in JVMS 4.1 (ClassFile.access_flags), 4.5 (field_info.access_flags), and 4.6 (method_info.access_flags), which gain the following rules:
4.1
At most one of the ACC_MODULE and ACC_PUBLIC flags may be set (JLS3 §6.6.1).
4.5
Fields of classes may set any of the flags in Table 4.4. However, a specific field of a class may have at most one of its ACC_PRIVATE, ACC_PROTECTED, ACC_MODULE, and ACC_PUBLIC flags set (JLS3 §8.3.1) and must not have both its ACC_FINAL and ACC_VOLATILE flags set (JLS3 §8.3.1.4).
All fields of interfaces must have their ACC_STATIC and ACC_FINAL and either ACC_PUBLIC or ACC_MODULE flags set; they may have their ACC_SYNTHETIC flag set and must not have any of the other flags in Table 4.4 set (JLS3 §9.3).
4.6
Methods of classes may set any of the flags in Table 4.5. However, a specific method of a class may have at most one of its ACC_PRIVATE, ACC_PROTECTED, ACC_MODULE, and ACC_PUBLIC flags set (JLS3 §8.4.3).
All interface methods must have their ACC_ABSTRACT and either ACC_PUBLIC or ACC_MODULE flags set; they may have their ACC_VARARGS, ACC_BRIDGE and ACC_SYNTHETIC flags set and must not have any of the other flags in Table 4.5 set (JLS3 §9.4).
A specific instance initialization method (§3.9) may have at most one of its ACC_PRIVATE, ACC_PROTECTED, ACC_MODULE, and ACC_PUBLIC flags set, and may also have its ACC_STRICT, ACC_VARARGS and ACC_SYNTHETIC flags set, but must not have any of the other flags in Table 4.5 set.
In the InnerClasses attribute's inner_class_access_flags table, ACC_MODULE means "Marked module in source. May only be set if the ClassFile has a Module attribute."

The ACC_PUBLIC flag in all access_flags is now defined as "Declared public; may be accessed from outside its package or module."

4.8.21 The Module attribute

The Module attribute is a fixed-length attribute in the attributes table of a ClassFile (JVMS 4.1) structure. The Module attribute records the named module (JLS 7.4.5) to which the class belongs. A ClassFile structure without a Module attribute is considered to be a member of the unnamed module (JLS 7.4.6).

There can be no more than one Module attribute in the attributes table of a given ClassFile structure. A Module attribute may only appear in a ClassFile structure that represents a class whose binary name in internal form (as given by the constant pool entry referenced by the name_index item of the CONSTANT_Class_info structure referenced by ClassFile.this_class) is qualified, i.e. contains at least one /.

The Module attribute has the following format:

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 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 must be 2.
module_id_index
The value of the module_id_index item must be a valid index into the constant_pool table. The constant_pool entry at that index must be a CONSTANT_ModuleId_info structure representing the name and version of the named module of which this ClassFile is a member. The module name must be encoded in internal form (4.2.1). If the version_index item of the CONSTANT_ModuleId_info structure is 0, then this ClassFile is a member of any version of the module named by the name_index item.
The CONSTANT_ModuleId_info structure has the following format:
CONSTANT_ModuleId_info {
  u1 tag;
    // 13
  u2 name_index;
    // Points to a CONSTANT_Utf8_info representing module name
  u2 version_index;
    // Points to a CONSTANT_Utf8_info representing module version
}

The module-info.class file

A module compilation unit (module-info.java) is compiled to a ClassFile structure like any other compilation unit. It follows the precedent set by compiling a package compilation unit (package-info.java) which has been possible since Java 5.0. Since neither compilation unit describes a class as such, the following conventions are adopted for their ClassFile structures.

package-info.class

module-info.class

Attributes for the module-info.class file

The ModuleRequires attribute is defined as follows:
ModuleRequires_attribute {
  u2 attribute_name_index;
  u4 attribute_length;
  u2 requires_length;
  { u2 requires_index; u1 flags; } requires_table[depends_length];
}
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 "ModuleRequires".
attribute_length
The value of the attribute_length item is the length of the attribute excluding the initial six bytes.
requires_length
The value of the requires_length indicates the number of entries in the requires_table.
requires_table
Each requires_index must be a valid index into the constant_pool table. The constant_pool entry at that index must be a CONSTANT_ModuleId_info structure representing the target module on which this module depends.
flags: 0x01 if this dependency on the target module is optional
flags: 0x02 if the target module's types must be loaded by the
            same defining classloader as the
            types of the module represented by this ClassFile
flags: 0x04 if the target module's public types are NOT observable to
            types of the module represented by this ClassFile
The ModulePermits attribute is defined as follows:
ModulePermits_attribute {
  u2 attribute_name_index;
  u4 attribute_length;
  u2 permits_length;
  { u2 permits_index } permits_table[permits_length];
}
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 "ModulePermits".
attribute_length
The value of the attribute_length item is the length of the attribute excluding the initial six bytes.
permits_length
The value of the permits_length indicates the number of entries in the permits_table.
permits_table
The value of each permits_index in this 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 which is permitted by the host system to have a dependency on the module represented by this ClassFile.
The ModuleProvides attribute is defined as follows:
ModuleProvides_attribute {
  u2 attribute_name_index;
  u4 attribute_length;
  u2 provides_length;
  { u2 provides_index; } provides_table[provides_length];
}
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 "ModuleProvides".
attribute_length
The value of the attribute_length item is the length of the attribute excluding the initial six bytes.
provides_length
The value of the provides_length indicates the number of entries in the provides_table.
provides_table
The value of each provides_index in this item must be a valid index into the constant_pool table. The constant_pool entry at that index must be a CONSTANT_ModuleId_info structure representing a module identity that is an alias for the module represented by this ClassFile.