JDK-8275509: (jlink) SystemModulesPlugin generates a jdk.internal.module.SystemModules$all.class which isn't reproducible

Jaikiran Pai jai.forums2013 at gmail.com
Fri Oct 22 04:09:38 UTC 2021


Hello Ioi,

On 21/10/21 9:59 pm, Ioi Lam wrote:
>
>
> On 10/21/21 5:25 AM, Alan Bateman wrote:
>> On 21/10/2021 10:49, Jaikiran Pai wrote:
>>> :
>>>
>>> Digging into it, it appears that since the ModuleDescriptor#equals() 
>>> calls equals() on enum types (in this specific case on 
>>> ModuleDescriptor.Requires.Modifier) and since enum type equality is 
>>> implemented as identity checks, those identity checks are 
>>> surprisingly failing. More specifically 
>>> ModuleDescriptor.Requires.Modifier.MANDATED == 
>>> ModuleDescriptor.Requires.Modifier.MANDATED is equating to false 
>>> because at runtime I see that two different instances of 
>>> ModuleDescriptor.Requires.Modifier.MANDATED have been loaded (by the 
>>> same boot module classloader). Although I use 
>>> ModuleDescriptor.Requires.Modifier.MANDATED as an example, the same 
>>> is reproducible with other enum values like 
>>> ModuleDescriptor.Requires.Modifier.TRANSITIVE.
>>>
>>> This appears to be specific to CDS since running the above program 
>>> with:
>>>
>>> java -Xshare:off EnumEquality
>>>
>>> succeeds and the ModuleDescriptor equality check passes.
>>>
>>> In short, it looks like there is some general issue with CDS and 
>>> equality checks with enums and perhaps deserves a separate JBS issue?
>> I've asked Ioi Lam to comment on this, off-hand I'm not aware of any 
>> issues with CDS here but it may be related to the archiving of object 
>> graphs.
>>
>> -Alan
>
> Hi Jaikiran and Alan,
>
> Thanks for reporting this issue. It's a bug in CDS. I have filed 
> https://bugs.openjdk.java.net/browse/JDK-8275731 and am working on a fix.

Thank you for looking into this.

>
> This is my initial analysis of the problem.
>
> ====>>> Can anyone think of similar problems that may happen elsewhere?
>
> The static constructors of enum classes are executed at both CDS dump 
> time and run time. E.g.,
>
>     public enum Modifier {
>         OPEN
>     }
>
> The <clinit> method essentially does this:
>
>     public static final Modifier OPEN = new Modifier("OPEN");
>
> If a reference of Modifier.OPEN is stored inside the CDS archived heap 
> during dump time, it will be different than the value of Modifier.OPEN 
> that is re-created at runtime by the execution of Modifier.<clinit>

I have almost next to nothing knowledge about CDS internals. My only 
understanding of it is based on some documentation that I have read. One 
of them being this one 
https://docs.oracle.com/en/java/javase/17/vm/class-data-sharing.html#GUID-7EAA3411-8CF0-4D19-BD05-DF5E1780AA91.

Based on that documentation (and other similar ones), it was my 
understanding that CDS was meant to store/share class "metadata" like it 
states in that doc:

"When the JVM starts, the shared archive is memory-mapped to allow 
sharing of read-only JVM metadata for these classes among multiple JVM 
processes."

But from what you explain in that enum example, it looks like it also 
stores class instance data that is computed at build time on the host 
where the JDK image was generated? Did I understand it correctly? Is 
this only for enums or does it also store the static initialization data 
of "class" types too? If it does store the static init data of class 
types too, then wouldn't such data be host/build time specific and as 
such the classes that need to be enrolled into the default CDS archive 
of the JDK should be very selective (by reviewing what they do in their 
static init)? Like I said, I haven't looked into this in detail so 
perhaps it already is selective in the JDK build?

-Jaikiran




More information about the core-libs-dev mailing list