ModuleClass

Jonathan Gibbons Jonathan.Gibbons at Sun.COM
Tue Mar 3 12:19:38 PST 2009


Yes, it's a change.  It's not in line with what we previously agreed and 
which I have already implemented.

Yes, there was a bug in the impl such that I was using CONSTANT_Utf8 
instead of CONSTANT_Class, and I have spent the morning fixing that and 
writing related test programs, and now you're telling me you're changing 
the spec on me.

Your proposed spec change does *not* bring this in line with 
ModuleInfoReader's current parsing, because that still uses an even 
older version of the spec that uses the "ModuleMain" attribute, not 
"ModuleClass".

-- Jon

Alex Buckley wrote:
> I guess I should have been clearer: the spec section starts at "The 
> ModuleClass attribute is defined as follows...". "For now" is 
> certainly not in the spec!
>
> Nothing has changed. I wrote up ModuleClass in line with Mark's 
> comment "I suspect we really want ModuleClass to name a class rather 
> than just convey a plain utf8 string" and with ModuleInfoReader's 
> current parsing.
>
> Alex
>
> Jonathan Gibbons wrote:
>> NOOOOOOOOOOOOOO.
>>
>> Please stop gratuitous changing of the spec like this!
>>
>> I guess I distrust a spec that includes the words "For now".  
>> -- Jon
>>
>> On Mar 3, 2009, at 11:47 AM, Alex Buckley wrote:
>>
>>> Being able to put flags in the main class attribute would probably 
>>> be worthwhile if multiple main class attributes were allowed: "Main 
>>> class M is flagged as an FX 1.1 app", "Main class N is flagged as a 
>>> bundle activator and can be assumed to implement interface...".
>>>
>>> However, I think for now one ModuleClass attribute is enough, 
>>> pointing to a CONSTANT_Class_info, and without flags.
>>>
>>> The ModuleClass attribute is defined as follows:
>>>
>>> ModuleClass_attribute {
>>>  u2 attribute_name_index;
>>>  u4 attribute_length;
>>>  u2 main_class;
>>> }
>>>
>>> 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 
>>> "ModuleClass".
>>>
>>> attribute_length
>>>    The value of the attribute_length item is the length of the 
>>> attribute excluding the initial six bytes.
>>>
>>> main_class
>>>    The value of the main_class 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 name of the class 
>>> which the host system should treat as the entrypoint to the module.
>>>
>>> Attached is an updated (+ tiny corrections) classfile spec.
>>>
>>> Alex
>>>
>>> Jonathan Gibbons wrote:
>>>> Alex suggested adding it when I asked him for a spec of the 
>>>> ModuleClass
>>>> attribute.  At the time, the thought was to be able to mark the 
>>>> type of class,
>>>> main class, applet etc.  A more topical example, from a separate email
>>>> thread going on now, would be to be able to mark a JavaFX class.
>>>> [Kumar is working on changes to the launcher to make it capable of
>>>> starting FX programs, given an FX main class.] So the ability to give
>>>> simple attributes regarding the class appears somewhat reasonable.
>>>> I guess the updated classfile spec got pre-empted by FOSDEM ;-)
>>>> -- Jon
>>>> On Mar 3, 2009, at 9:21 AM, Mark Reinhold wrote:
>>>>>> Date: Tue, 03 Mar 2009 07:54:39 -0800
>>>>>> From: jonathan.gibbons at sun.com <mailto:jonathan.gibbons at sun.com>
>>>>>
>>>>>> Point noted about the incorrect use of CONSTANT_Utf8 instead of
>>>>>> CONSTANT_Class.  I'll check that out.
>>>>>
>>>>> Okay, thanks.
>>>>>
>>>>>>                                      Also, if I recall correctly,
>>>>>> that item is followed by an array of Utf8 strings representing an 
>>>>>> open
>>>>>> ended set of flags/modifiers, similar to that used for the requires
>>>>>> entry. If nothing else, you might need to skip over them if there is
>>>>>> any info to follow.
>>>>>
>>>>> Hmm, didn't know that, and neither does the ModuleInfoReader code.
>>>>>
>>>>> I don't recall having discussed the need for modifiers in the 
>>>>> main-class
>>>>> declaration.  Do we have use cases?
>>>>>
>>>>> - Mark
>>>
>>>
>>>   |ClassFile| changes in v51.0 for Modules
>>>
>>>
>>>     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
>>>
>>>     * |major_version, minor_version|: >=49.0
>>>     * |this_class|: [Package name in internal form 
>>> (4.2.1)]/package-info
>>>     * |access_flags|: v49: ACC_INTERFACE ACC_ABSTRACT >=v50:
>>>       ACC_INTERFACE ACC_ABSTRACT ACC_SYNTHETIC
>>>     * |super_class|, |interfaces_count|, |fields_count|,
>>>       |methods_count|: 0
>>>     * |attributes|: except for |Module|, |SourceFile|,
>>>       |RuntimeVisibleAnnotations| and |RuntimeInvisibleAnnotations|,
>>>       none of the pre-defined attributes in JVMS 4.7 may appear.
>>>
>>>       module-info.class
>>>
>>>     * |major_version, minor_version|: >=51.0
>>>     * |this_class|: [Module name in internal form (4.2.1)]/module-info
>>>     * |access_flags|: ACC_INTERFACE ACC_ABSTRACT ACC_SYNTHETIC
>>>     * |attributes|: One |Module| attribute must be present, for the
>>>       module name given in the |this_class| item.
>>>     * |super_class|, |interfaces_count|, |fields_count|,
>>>       |methods_count|: 0
>>>     * |attributes|: One |Module| attribute must be present, for the
>>>       module name given in the |this_class| item. At most one of each
>>>       of the |ModuleRequires|, |ModulePermits|, |ModuleProvides|, and
>>>       |ModuleClass| attributes must be present if the module has
>>>       metadata. Except for these attributes and |SourceFile|,
>>>       |RuntimeVisibleAnnotations|, and |RuntimeInvisibleAnnotations|,
>>>       none of the pre-defined attributes in JVMS 4.7 may appear.
>>>     * A module name may be referenced by at most one entry in the
>>>       |requires_table| of a |ModuleRequires| attribute and at most one
>>>       entry in the |permits_table| of a |ModulePermits| attribute and
>>>       at most one entry in the |provides_table| of a |ModuleProvides|
>>>       attribute of a |ClassFile|.
>>>
>>>     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[requires_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|.
>>> The |ModuleClass| attribute is defined as follows:
>>> ModuleClass_attribute {
>>>   u2 attribute_name_index;
>>>   u4 attribute_length;
>>>   u2 main_class;
>>> }
>>>
>>> |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 "ModuleClass". |attribute_length|
>>>     The value of the |attribute_length| item is the length of the
>>>     attribute excluding the initial six bytes. |main_class|
>>>     The value of the |main_class| 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 name of
>>>     the class which the host system should treat as the entrypoint to
>>>     the module.
>>




More information about the jigsaw-dev mailing list