{
  "id": "java/class-circularity-error",
  "signature": "java.lang.ClassCircularityError: <class name>",
  "signature_zh": "java.lang.ClassCircularityError：<类名>",
  "regex": "java\\.lang\\.ClassCircularityError: [\\w.$]+",
  "domain": "java",
  "category": "module_error",
  "subcategory": null,
  "root_cause": "The JVM detected a circular dependency during class initialization, where class A's static initializer triggers loading of class B, which in turn triggers loading of class A again before A's initialization is complete, causing an infinite loop that the JVM cannot resolve.",
  "root_cause_type": "generic",
  "root_cause_zh": "JVM在类初始化期间检测到循环依赖，其中类A的静态初始化器触发了类B的加载，而类B又触发了类A的加载，此时A的初始化尚未完成，导致JVM无法解决的无限循环。",
  "versions": [
    {
      "version": "Java 8",
      "introduced": null,
      "deprecated": null,
      "removed": null,
      "behavior_change": null,
      "status": "active"
    },
    {
      "version": "Java 11",
      "introduced": null,
      "deprecated": null,
      "removed": null,
      "behavior_change": null,
      "status": "active"
    },
    {
      "version": "Java 17",
      "introduced": null,
      "deprecated": null,
      "removed": null,
      "behavior_change": null,
      "status": "active"
    },
    {
      "version": "Java 21",
      "introduced": null,
      "deprecated": null,
      "removed": null,
      "behavior_change": null,
      "status": "active"
    }
  ],
  "os_specific": {},
  "dead_ends": [
    {
      "action": "Remove static initializers entirely from the affected classes",
      "why_fails": "Static initializers often hold essential configuration or resource loading. Removing them may break the application's functionality. The circular dependency should be resolved by refactoring, not by elimination.",
      "fail_rate": 0.75,
      "condition": "",
      "sources": []
    },
    {
      "action": "Add Thread.sleep() in static initializers to break the cycle",
      "why_fails": "Sleeping does not break the circular dependency; it only delays the crash. The JVM will still detect the cycle when the other class is loaded, and the error will occur after the sleep.",
      "fail_rate": 0.95,
      "condition": "",
      "sources": []
    }
  ],
  "workarounds": [
    {
      "action": "Refactor the circular dependency by moving shared static fields or methods to a third utility class. For example, if class A uses `B.CONSTANT` and class B uses `A.CONSTANT`, create a `Constants` class: `public class Constants { public static final int VALUE = 42; }` and have both A and B reference it.",
      "success_rate": 0.85,
      "how": "Refactor the circular dependency by moving shared static fields or methods to a third utility class. For example, if class A uses `B.CONSTANT` and class B uses `A.CONSTANT`, create a `Constants` class: `public class Constants { public static final int VALUE = 42; }` and have both A and B reference it.",
      "condition": "",
      "sources": []
    },
    {
      "action": "Use lazy initialization for static fields that cause the cycle. Replace `public static final Foo foo = new Foo();` with a holder class pattern: `private static class Holder { static final Foo foo = new Foo(); }` and access it via `Holder.foo`. This defers loading until the field is actually accessed.",
      "success_rate": 0.8,
      "how": "Use lazy initialization for static fields that cause the cycle. Replace `public static final Foo foo = new Foo();` with a holder class pattern: `private static class Holder { static final Foo foo = new Foo(); }` and access it via `Holder.foo`. This defers loading until the field is actually accessed.",
      "condition": "",
      "sources": []
    },
    {
      "action": "If using a dependency injection framework like Spring, ensure beans are not involved in circular references. Use `@Lazy` annotation on one of the beans: `@Lazy @Component public class A { ... }` to break the initialization cycle.",
      "success_rate": 0.75,
      "how": "If using a dependency injection framework like Spring, ensure beans are not involved in circular references. Use `@Lazy` annotation on one of the beans: `@Lazy @Component public class A { ... }` to break the initialization cycle.",
      "condition": "",
      "sources": []
    }
  ],
  "workarounds_zh": [
    "Refactor the circular dependency by moving shared static fields or methods to a third utility class. For example, if class A uses `B.CONSTANT` and class B uses `A.CONSTANT`, create a `Constants` class: `public class Constants { public static final int VALUE = 42; }` and have both A and B reference it.",
    "Use lazy initialization for static fields that cause the cycle. Replace `public static final Foo foo = new Foo();` with a holder class pattern: `private static class Holder { static final Foo foo = new Foo(); }` and access it via `Holder.foo`. This defers loading until the field is actually accessed.",
    "If using a dependency injection framework like Spring, ensure beans are not involved in circular references. Use `@Lazy` annotation on one of the beans: `@Lazy @Component public class A { ... }` to break the initialization cycle."
  ],
  "transition_graph": {
    "leads_to": [],
    "preceded_by": [],
    "frequently_confused_with": []
  },
  "official_doc_url": "https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/ClassCircularityError.html",
  "official_doc_section": null,
  "error_code": null,
  "verification_tier": "ai_generated",
  "confidence": 0.82,
  "fix_success_rate": 0.8,
  "resolvable": "true",
  "first_seen": "2024-01-18",
  "last_confirmed": "2024-06-01",
  "last_updated": "2024-06-01",
  "evidence_count": 1,
  "tags": [],
  "locale": "en",
  "aliases": []
}