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.
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>
Thanks
- Ioi