ModuleClass

Jonathan Gibbons Jonathan.Gibbons at Sun.COM
Tue Mar 3 12:56:34 PST 2009


On Mar 3, 2009, at 12:31 PM, Alex Buckley wrote:

> I'm confused. In:
>
> ModuleClass_attribute {
> u2 attribute_name_index;
> u4 attribute_length;
> u2 main_class;
> }
>
> attribute_name_index points to a "ModuleClass" string, which is what  
> Mark's patch from 21:26 yesterday used and a name he seemed happy  
> with. (I think the bit of that patch he was loathe to commit was  
> reading a class name from a Utf8.)
>
> main_class points to a CONSTANT_Class, which you agreed at 07:54 was  
> the right thing to do.
>
> I can add an array of flags after main_class - no ModuleInfoReader  
> code reads them yet anyway. Does this reflect what javac emits:
>
> ModuleClass_attribute {
> u2 attribute_name_index;
> u4 attribute_length;
> u2 main_class;
> u2 flags_length;
> { u2 flag; /*Points to Utf8_info*/ } main_class_flags[flags_length];
> }
>

Yes, this is what I understood we agreed to a couple of weeks back,  
and which corresponds to javac/javap/classfile.

-- Jon



> Alex
>
> Jonathan Gibbons wrote:
>> 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