ModuleClass
Alex Buckley
Alex.Buckley at Sun.COM
Tue Mar 3 12:31:03 PST 2009
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];
}
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