# java.lang.ClassCircularityError: <class name>

- **ID:** `java/class-circularity-error`
- **Domain:** java
- **Category:** module_error
- **Verification:** ai_generated
- **Fix Rate:** 80%

## 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.

## Version Compatibility

| Version | Status | Introduced | Deprecated |
|---------|--------|------------|------------|
| Java 8 | active | — | — |
| Java 11 | active | — | — |
| Java 17 | active | — | — |
| Java 21 | active | — | — |

## Workarounds

1. **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.** (85% success)
   ```
   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.
   ```
2. **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.** (80% success)
   ```
   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.
   ```
3. **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.** (75% success)
   ```
   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.
   ```

## Dead Ends

- **Remove static initializers entirely from the affected classes** — 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. (75% fail)
- **Add Thread.sleep() in static initializers to break the cycle** — 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. (95% fail)
