JDK-8275731 : CDS archived enums objects are recreated at runtime
  • Type: Bug
  • Component: hotspot
  • Sub-Component: runtime
  • Affected Version: 18
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2021-10-21
  • Updated: 2022-12-19
  • Resolved: 2022-02-28
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 19
19 b12Fixed
Related Reports
Duplicate :  
Relates :  
Description
As reported in https://mail.openjdk.java.net/pipermail/core-libs-dev/2021-October/082709.html

The static constructors of enum classes are executed at both CDS dump time and run time. E.g., 

    public enum Modifier {
        OPEN,
    }

The Modifier::<clinit> method is a synthetic method created by javac. It essentially does this:

    public static final Modifier OPEN = new Modifier("OPEN");

If a reference of Modifier.OPEN is stored inside the CDS archived heap, it will be different than the value of Modifier.OPEN that is re-created at runtime by the execution of Modifier.<clinit>

==============================
import java.lang.module.*;
import java.io.*;
import java.util.*;

public class EnumEquality {

    public static void main(final String[] args) throws Exception {
        String moduleName = "java.sql";
        // load the "java.sql" module from boot layer
        Optional<Module> bootModule = ModuleLayer.boot().findModule(moduleName);
        if (bootModule.isEmpty()) {
            throw new RuntimeException(moduleName + " module is missing in boot layer");
        }
        ModuleDescriptor m1 = bootModule.get().getDescriptor();
        // now recreate the same module using the ModuleDescriptor.read on the module's module-info.class
        ModuleDescriptor m2;
        try (InputStream moduleInfo = bootModule.get().getResourceAsStream("module-info.class")) {
            if (moduleInfo == null) {
                throw new RuntimeException("Could not locate module-info.class in " + moduleName + " module");
            }
            // this will internally use a ModuleDescriptor.Builder to construct the ModuleDescriptor
            m2 = ModuleDescriptor.read(moduleInfo);
        }
        if (!m1.equals(m2)) {
            // root cause - the enums aren't "equal"
            for (ModuleDescriptor.Requires r1 : m1.requires()) {
                if (r1.name().equals("java.base")) {
                    for (ModuleDescriptor.Requires r2 : m2.requires()) {
                        if (r2.name().equals("java.base")) {
                            System.out.println("Modifiers r1 " + r1.modifiers() + " r2 " + r2.modifiers()
                                + " --> equals? " + r1.modifiers().equals(r2.modifiers()));
                        }
                    }
                }
            }

            throw new RuntimeException("ModuleDescriptor(s) aren't equal: \n" + m1 + "\n" + m2);
        }
        System.out.println("Success");
    }
}





Comments
[17u] Hi Leslie, please give a reason why you want to backport this change. Why is it needed in 17? I will not approve any changes referring only to this one, as long as this one does not have a reason why it is needed. Given the size of the change and the many prerequisites you list, I think it is a bad candidate for backporting.
19-12-2022

In order to backport this issue to jdk 17u, the following issues must be backported first, in the order of a. JDK-8267189: Remove duplicated unregistered classes from dynamic archive b. JDK-8268821: Split systemDictionaryShared.cpp c. JDK-8269004: Implement ResizableResourceHashtable d. JDK-8270061: Change parameter order of ResourceHashtable e. JDK-8270803: Reduce CDS API verbosity f. JDK-8270489: Support archived heap objects in EpsilonGC
02-12-2022

-Fix request [18u] The patch applies clean except manually edit below source file: * src/hotspot/share/cds/dumpTimeClassInfo.cpp Include "cds/runTimeClassInfo.hpp" header file. * src/hotspot/share/cds/heapShared.hpp Add initialize_enum_klass(...) defination. * src/hotspot/share/oops/klass.hpp Change Enumeration. Testing jtreg tier1~3 now.- Christoph suggested me backport to 17u owing to jdk18u is not maintained any more.
25-11-2022

A pull request was submitted for review. URL: https://git.openjdk.org/jdk18u/pull/179 Date: 2022-11-25 07:54:22 +0000
25-11-2022

Changeset: d983d108 Author: Ioi Lam <iklam@openjdk.org> Date: 2022-02-28 20:33:18 +0000 URL: https://git.openjdk.java.net/jdk/commit/d983d108c565654e717e2811d88aa94d982da2f5
28-02-2022

RT Triage team: given the complexity of the changes we are deferring this to JDK 19.
21-12-2021

Hi Ioi, I'll take a look of your change https://github.com/openjdk/jdk/pull/6653. Thanks.
03-12-2021

Changed to P3 as this may interfere with user programs that inspect the module graph.
01-12-2021

Hi [~jiangli], thanks for the information. I have created a patch for this bug, but it doesn't require the support of archiving mirror objects. That's because Enum class have special <clinit> methods. Please see https://github.com/openjdk/jdk/pull/6653
01-12-2021

The chain of reference to the enum objects are in the attachment https://bugs.openjdk.java.net/secure/attachment/97242/enum_warning.txt
01-12-2021

ILW = MLM = P4
26-10-2021

Pre-initializing CDS archived Enums require supporting the mirror objects within the archived object sub-graphs. I've implemented that support for mirrors (as a foundation for more general class pre-initialization) in http://cr.openjdk.java.net/~jiangli/Leyden/general_class_pre_initialization_core_mechanism/, for JDK-8233887. With that, it supports pre-init Enums and other classes more generally. I'm in the middle of integrating that patch and open sourcing additional bug fixes to https://github.com/adoptium/jdk11u-fast-startup-incubator for contributing back to OpenJDK as the main goal. Ioi, please let me know if you are interested in forward porting the changes to the last code base, or collaborating in any forms.
25-10-2021