Skip to content

Commit e0ebbdb

Browse files
dmealingclaude
andcommitted
release(java): 7.20.12 — #233 maven parallel-build deadlock fix (Maven-only)
Maven Central only (npm/PyPI/NuGet stay at 0.20.11 — the fix is Java-only). Bumps the 13 publishable modules 7.20.11 -> 7.20.12. Ships #233: RegistryBootstrap warm-up + per-instance activeLoaders key + threadSafe generate/verify/docs. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HLoJkFSyoticveo5ehMUAr
1 parent a722b7f commit e0ebbdb

19 files changed

Lines changed: 28 additions & 18 deletions

File tree

CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,16 @@ here. The format follows [Keep a Changelog](https://keepachangelog.com/), and
55
this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html)
66
(pre-1.0; MINOR bumps may introduce breaking changes with notice).
77

8+
## [7.20.12] — 2026-08-02
9+
10+
**Maven-only PATCH** — Maven Central `7.20.12` (npm/PyPI/NuGet unchanged at `0.20.11`; the fix is Java-only, so only the Maven line moves — Maven now runs one patch ahead of the shared `20.11`, mirroring how npm runs a patch ahead with npm-only fixes). Fixes **[#233](https://github.com/metaobjectsdev/metaobjects/issues/233)**: a multi-module Maven reactor building `metaobjects-maven-plugin` in **parallel** (`mvn -T<N>`) deadlocked/hung; the serial default (`-T1`) always worked. Two compounding causes, both fixed:
11+
12+
- **Deadlock (Part A).** On the first load, several **independently-locked process-global registry singletons** — `RegistryManifest.defaultLoaderRegistry()` (DEFAULT_LOCK), `MetaDataRegistry.getInstance()` (INSTANCE_LOCK, reached via `ConstraintEnforcer.getInstance()` on the first `addChild`), and `ServiceRegistryFactory.getDefault()`, plus the JVM class-init locks of the ~18 type providers — could be acquired by two loader threads in **different orders** (a classic lock-ordering deadlock). `MavenLoaderConfiguration` first-touches the sealed registry on the Maven worker thread with no timeout, so a deadlock there wedged the reactor forever. A new **`RegistryBootstrap.warmUpDefaults()`** deterministically initializes those singletons on a single thread under one lock **before** any parallel first-init can race them; it is called from `MetaDataLoader.initWithConcurrencyProtection` (covers every loader embedder — Spring, parallel test runners, servers — not just Maven) and the mojo `execute()`s (covers Maven's pre-`init()` eager registry touch).
13+
- **Cross-module loader sharing (Part B).** The load runs on `ForkJoinPool.commonPool()` via a static `activeLoaders` map keyed `class:subType:name` (no instance identity), so two reactor modules configuring a `<loader>` with the **same name** shared one init future — module B's `init()` returned module A's loader and left B's own tree UNINITIALIZED (silent wrong output, or the build failing with `MetaDataLoader [name] is not usable`). `MetaDataLoader.buildLoaderKey()` now includes a process-unique instance id, so the dedup only coalesces concurrent `init()` on the **same** instance.
14+
- The `generate` / `verify` / `docs` mojos are now declared `@Mojo(threadSafe = true)` — honest labeling that ships atomically with the fix (Maven 3.x does not serialize non-threadSafe mojos under `-T`, it only warns); `editor` (direct-invocation) and `agent-docs` (stub) intentionally remain unmarked.
15+
16+
Existing single-module `meta:gen` output is **byte-identical** (the warm-up only front-loads existing lazy init; the per-instance key changes only the dedup key). Verified with a 3-module `-T4` reactor before/after (unfixed: 8/8 runs fail on the shared-name module with `Phase: UNINITIALIZED`; fixed: 5/5 pass with per-module isolation) plus new unit tests (`LoaderKeyIsolationTest`, `RegistryBootstrapTest`, `MojoThreadSafeDescriptorTest`) and the full `metadata` + `maven-plugin` + `codegen-spring` + `codegen-kotlin` suites. Maven-only change (Java maven-plugin + metadata registry); no TS/Python/C# product changes. See `docs/superpowers/specs/2026-08-02-issue-233-maven-parallel-build-deadlock-design.md`.
17+
818
## [0.20.11] — 2026-08-02
919

1020
**Coordinated PATCH** — npm `0.20.11` · PyPI `0.20.11` · NuGet `0.20.11` · Maven Central `7.20.11`.

CLAUDE.md

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

server/java/codegen-base/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
<parent>
77
<groupId>com.metaobjects</groupId>
88
<artifactId>metaobjects</artifactId>
9-
<version>7.20.11</version>
9+
<version>7.20.12</version>
1010
</parent>
1111

1212
<artifactId>metaobjects-codegen-base</artifactId>

server/java/codegen-kotlin/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
<parent>
88
<groupId>com.metaobjects</groupId>
99
<artifactId>metaobjects</artifactId>
10-
<version>7.20.11</version>
10+
<version>7.20.12</version>
1111
</parent>
1212

1313
<artifactId>metaobjects-codegen-kotlin</artifactId>

server/java/codegen-mustache/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
<parent>
77
<groupId>com.metaobjects</groupId>
88
<artifactId>metaobjects</artifactId>
9-
<version>7.20.11</version>
9+
<version>7.20.12</version>
1010
</parent>
1111

1212
<artifactId>metaobjects-codegen-mustache</artifactId>

server/java/codegen-plantuml/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
<parent>
77
<groupId>com.metaobjects</groupId>
88
<artifactId>metaobjects</artifactId>
9-
<version>7.20.11</version>
9+
<version>7.20.12</version>
1010
</parent>
1111

1212
<artifactId>metaobjects-codegen-plantuml</artifactId>

server/java/codegen-spring/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
<parent>
77
<groupId>com.metaobjects</groupId>
88
<artifactId>metaobjects</artifactId>
9-
<version>7.20.11</version>
9+
<version>7.20.12</version>
1010
</parent>
1111

1212
<artifactId>metaobjects-codegen-spring</artifactId>

server/java/core-spring/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
<parent>
77
<groupId>com.metaobjects</groupId>
88
<artifactId>metaobjects</artifactId>
9-
<version>7.20.11</version>
9+
<version>7.20.12</version>
1010
</parent>
1111

1212
<artifactId>metaobjects-core-spring</artifactId>

server/java/integration-tests-kotlin/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
<parent>
88
<groupId>com.metaobjects</groupId>
99
<artifactId>metaobjects</artifactId>
10-
<version>7.20.11</version>
10+
<version>7.20.12</version>
1111
</parent>
1212

1313
<artifactId>metaobjects-integration-tests-kotlin</artifactId>

server/java/integration-tests/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
<parent>
88
<groupId>com.metaobjects</groupId>
99
<artifactId>metaobjects</artifactId>
10-
<version>7.20.11</version>
10+
<version>7.20.12</version>
1111
</parent>
1212

1313
<artifactId>metaobjects-integration-tests</artifactId>

0 commit comments

Comments
 (0)