You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@juneau.apache.org by ja...@apache.org on 2026/05/11 19:44:48 UTC

(juneau) 07/19: refactor(inject): TODO-15 phase-3 batch 7 — port BasicBeanStore.INSTANCE to v2

This is an automated email from the ASF dual-hosted git repository.

jamesbognar pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/juneau.git

commit 9a2537475359b8f36cc021ad7c2c31d4cb8e17c1
Author: James Bognar <ja...@jamesbog-ltmjqf2.internal.salesforce.com>
AuthorDate: Fri May 8 14:22:29 2026 -0400

    refactor(inject): TODO-15 phase-3 batch 7 — port BasicBeanStore.INSTANCE to v2
    
    Adds BasicBeanStore2.INSTANCE (typed as the concrete class for compatibility
    with WritableBeanStore-typed Builder ctors; documented as "treat as read-only")
    and migrates 13 consumer references from legacy BasicBeanStore.INSTANCE:
    
    - BasicTestCaptureCallLogger, BasicCallLogger, CallLogger.DEFAULT_RULE
    - ThrownStore.create() + parent-less ctor, MethodExecStore.create()
    - EncoderSet.create(), ParserSet (Builder + create), SerializerSet (Builder + create)
    - OpenApiUI.RESOURCES, SwaggerUI.RESOURCES
    - Swagger_Test, RestContext_Precedence_Test
    
    Skipped: legacy cp.* classes (BasicBeanStore, BeanCreator, BeanCreateMethodFinder,
    Messages, FileFinder) and tests of legacy classes (BeanStore_Test, FileFinder_Test) —
    they're being deleted in Phase 4 cutover.
    
    Updates TODO-15 plan with batch-6 + batch-7 status.
    
    Co-authored-by: Cursor <cu...@cursor.com>
---
 .../org/apache/juneau/bean/openapi3/ui/OpenApiUI.java    |  3 ++-
 .../org/apache/juneau/bean/swagger/ui/SwaggerUI.java     |  3 ++-
 .../apache/juneau/commons/inject/BasicBeanStore2.java    | 16 ++++++++++++++++
 .../main/java/org/apache/juneau/encoders/EncoderSet.java |  3 ++-
 .../main/java/org/apache/juneau/parser/ParserSet.java    |  5 +++--
 .../java/org/apache/juneau/serializer/SerializerSet.java |  5 +++--
 .../org/apache/juneau/rest/logger/BasicCallLogger.java   |  4 ++--
 .../juneau/rest/logger/BasicTestCaptureCallLogger.java   |  5 ++---
 .../java/org/apache/juneau/rest/logger/CallLogger.java   |  4 ++--
 .../org/apache/juneau/rest/stats/MethodExecStore.java    |  4 ++--
 .../java/org/apache/juneau/rest/stats/ThrownStore.java   |  6 +++---
 .../apache/juneau/rest/RestContext_Precedence_Test.java  |  5 ++---
 .../test/java/org/apache/juneau/rest/Swagger_Test.java   |  3 ++-
 todo/TODO-15-replace-basicbeanstore-with-v2.md           |  8 ++++----
 14 files changed, 47 insertions(+), 27 deletions(-)

diff --git a/juneau-bean/juneau-bean-openapi-v3/src/main/java/org/apache/juneau/bean/openapi3/ui/OpenApiUI.java b/juneau-bean/juneau-bean-openapi-v3/src/main/java/org/apache/juneau/bean/openapi3/ui/OpenApiUI.java
index 31204dc7ea..a6b1303f32 100644
--- a/juneau-bean/juneau-bean-openapi-v3/src/main/java/org/apache/juneau/bean/openapi3/ui/OpenApiUI.java
+++ b/juneau-bean/juneau-bean-openapi-v3/src/main/java/org/apache/juneau/bean/openapi3/ui/OpenApiUI.java
@@ -32,6 +32,7 @@ import org.apache.juneau.bean.html5.*;
 import org.apache.juneau.bean.openapi3.*;
 import org.apache.juneau.collections.*;
 import org.apache.juneau.commons.utils.*;
+import org.apache.juneau.commons.inject.*;
 import org.apache.juneau.cp.*;
 import org.apache.juneau.swap.*;
 import org.apache.juneau.commons.http.MediaType;
@@ -61,7 +62,7 @@ public class OpenApiUI extends ObjectSwap<OpenApi,Div> {
 
 	// @formatter:off
 	static final FileFinder RESOURCES = FileFinder
-		.create(BasicBeanStore.INSTANCE)
+		.create(BasicBeanStore2.INSTANCE)
 		.cp(OpenApiUI.class, null, true)
 		.dir(",")
 		.caching(Boolean.getBoolean("RestContext.disableClasspathResourceCaching.b") ? -1 : 1_000_000) // HTT - system property branch only triggers when property is set
diff --git a/juneau-bean/juneau-bean-swagger-v2/src/main/java/org/apache/juneau/bean/swagger/ui/SwaggerUI.java b/juneau-bean/juneau-bean-swagger-v2/src/main/java/org/apache/juneau/bean/swagger/ui/SwaggerUI.java
index 1e5658590e..656c57ae09 100644
--- a/juneau-bean/juneau-bean-swagger-v2/src/main/java/org/apache/juneau/bean/swagger/ui/SwaggerUI.java
+++ b/juneau-bean/juneau-bean-swagger-v2/src/main/java/org/apache/juneau/bean/swagger/ui/SwaggerUI.java
@@ -31,6 +31,7 @@ import org.apache.juneau.bean.html5.*;
 import org.apache.juneau.bean.swagger.*;
 import org.apache.juneau.collections.*;
 import org.apache.juneau.commons.utils.*;
+import org.apache.juneau.commons.inject.*;
 import org.apache.juneau.cp.*;
 import org.apache.juneau.swap.*;
 
@@ -59,7 +60,7 @@ public class SwaggerUI extends ObjectSwap<Swagger,Div> {
 
 	// @formatter:off
 	static final FileFinder RESOURCES = FileFinder
-		.create(BasicBeanStore.INSTANCE)
+		.create(BasicBeanStore2.INSTANCE)
 		.cp(SwaggerUI.class, null, true)
 		.dir(",")
 		.caching(Boolean.getBoolean("RestContext.disableClasspathResourceCaching.b") ? -1 : 1_000_000) // HTT - system property branch only triggers when property is set
diff --git a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/inject/BasicBeanStore2.java b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/inject/BasicBeanStore2.java
index 729d617539..b77028f046 100644
--- a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/inject/BasicBeanStore2.java
+++ b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/inject/BasicBeanStore2.java
@@ -62,6 +62,22 @@ import org.apache.juneau.commons.reflect.*;
 })
 public class BasicBeanStore2 implements WritableBeanStore {
 
+	/**
+	 * Static reusable empty instance.
+	 *
+	 * <p>
+	 * Useful as a placeholder when an API requires a {@link BeanStore} but the caller has no beans to
+	 * register &mdash; e.g. as the parent argument to a builder that only needs the bean store for
+	 * downstream parameter resolution.
+	 *
+	 * <p>
+	 * <b>Treat this instance as read-only.</b>  It's typed as the concrete class so it can be passed
+	 * to APIs that take {@link WritableBeanStore} or {@code BasicBeanStore2}, but callers should not
+	 * call any mutating methods on it &mdash; doing so would leak state between unrelated callers.
+	 * Code that legitimately needs to add beans should construct its own {@code new BasicBeanStore2()}.
+	 */
+	public static final BasicBeanStore2 INSTANCE = new BasicBeanStore2();
+
 	// Property name constants
 	private static final String PROP_bean = "bean";
 	private static final String PROP_defaults = "defaults";
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/encoders/EncoderSet.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/encoders/EncoderSet.java
index d6ad4b613a..c2b6e53208 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/encoders/EncoderSet.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/encoders/EncoderSet.java
@@ -26,6 +26,7 @@ import java.util.*;
 import java.util.concurrent.*;
 
 import org.apache.juneau.*;
+import org.apache.juneau.commons.inject.BasicBeanStore2;
 import org.apache.juneau.commons.inject.BeanStore;
 import org.apache.juneau.commons.inject.WritableBeanStore;
 import org.apache.juneau.commons.reflect.*;
@@ -270,7 +271,7 @@ public class EncoderSet {
 	 * @return A new builder for this object.
 	 */
 	public static Builder create() {
-		return new Builder(BasicBeanStore.INSTANCE);
+		return new Builder(BasicBeanStore2.INSTANCE);
 	}
 
 	/**
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/ParserSet.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/ParserSet.java
index 0019a144d7..211d60ade6 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/ParserSet.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/ParserSet.java
@@ -17,6 +17,7 @@
 package org.apache.juneau.parser;
 
 import org.apache.juneau.commons.http.MediaType;
+import org.apache.juneau.commons.inject.BasicBeanStore2;
 import org.apache.juneau.commons.inject.WritableBeanStore;
 import static java.util.stream.Collectors.*;
 import static org.apache.juneau.commons.reflect.ReflectionUtils.*;
@@ -134,7 +135,7 @@ public class ParserSet {
 		 * @param copyFrom The parser group that we're copying settings and parsers from.
 		 */
 		protected Builder(ParserSet copyFrom) {
-			super(copyFrom.getClass(), BasicBeanStore.INSTANCE);
+			super(copyFrom.getClass(), BasicBeanStore2.INSTANCE);
 			this.entries = list((Object[])copyFrom.entries);
 		}
 
@@ -454,7 +455,7 @@ public class ParserSet {
 	 * @return A new builder for this object.
 	 */
 	public static Builder create() {
-		return new Builder(BasicBeanStore.INSTANCE);
+		return new Builder(BasicBeanStore2.INSTANCE);
 	}
 
 	/**
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/SerializerSet.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/SerializerSet.java
index e83e7dd658..bc40c13463 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/SerializerSet.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/SerializerSet.java
@@ -19,6 +19,7 @@ package org.apache.juneau.serializer;
 import org.apache.juneau.commons.http.MediaRanges;
 import org.apache.juneau.commons.http.MediaRange;
 import org.apache.juneau.commons.http.MediaType;
+import org.apache.juneau.commons.inject.BasicBeanStore2;
 import org.apache.juneau.commons.inject.WritableBeanStore;
 import static java.util.stream.Collectors.*;
 import static org.apache.juneau.commons.reflect.ReflectionUtils.*;
@@ -134,7 +135,7 @@ public class SerializerSet {
 		 * @param copyFrom The serializer group that we're copying settings and serializers from.
 		 */
 		protected Builder(SerializerSet copyFrom) {
-			super(copyFrom.getClass(), BasicBeanStore.INSTANCE);
+			super(copyFrom.getClass(), BasicBeanStore2.INSTANCE);
 			this.entries = list((Object[])copyFrom.entries);
 		}
 
@@ -451,7 +452,7 @@ public class SerializerSet {
 	 * @return A new builder for this object.
 	 */
 	public static Builder create() {
-		return new Builder(BasicBeanStore.INSTANCE);
+		return new Builder(BasicBeanStore2.INSTANCE);
 	}
 
 	/**
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/logger/BasicCallLogger.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/logger/BasicCallLogger.java
index 19650dc5a6..e342cdacbf 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/logger/BasicCallLogger.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/logger/BasicCallLogger.java
@@ -19,7 +19,7 @@ package org.apache.juneau.rest.logger;
 import static java.util.logging.Level.*;
 import static org.apache.juneau.rest.logger.CallLoggingDetail.*;
 
-import org.apache.juneau.commons.inject.BeanStore;
+import org.apache.juneau.commons.inject.*;
 import org.apache.juneau.cp.*;
 import org.apache.juneau.rest.*;
 
@@ -45,7 +45,7 @@ public class BasicCallLogger extends CallLogger {
 	 * Uses the same settings as {@link CallLogger}.
 	 */
 	public BasicCallLogger() {
-		super(BasicBeanStore.INSTANCE);
+		super(BasicBeanStore2.INSTANCE);
 	}
 
 	/**
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/logger/BasicTestCaptureCallLogger.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/logger/BasicTestCaptureCallLogger.java
index b0f842ab0a..d90ffe0bd8 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/logger/BasicTestCaptureCallLogger.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/logger/BasicTestCaptureCallLogger.java
@@ -23,8 +23,7 @@ import java.util.concurrent.atomic.*;
 import java.util.logging.*;
 
 import org.apache.juneau.assertions.*;
-import org.apache.juneau.commons.inject.BeanStore;
-import org.apache.juneau.cp.*;
+import org.apache.juneau.commons.inject.*;
 
 /**
  *
@@ -85,7 +84,7 @@ public class BasicTestCaptureCallLogger extends CallLogger {
 	 * Uses the same settings as {@link CallLogger}.
 	 */
 	public BasicTestCaptureCallLogger() {
-		super(BasicBeanStore.INSTANCE);
+		super(BasicBeanStore2.INSTANCE);
 	}
 
 	/**
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/logger/CallLogger.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/logger/CallLogger.java
index 4668406934..0fdc6a2ea8 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/logger/CallLogger.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/logger/CallLogger.java
@@ -31,7 +31,7 @@ import java.util.logging.*;
 
 import org.apache.juneau.*;
 import org.apache.juneau.commons.collections.*;
-import org.apache.juneau.commons.inject.BeanStore;
+import org.apache.juneau.commons.inject.*;
 import org.apache.juneau.commons.utils.*;
 import org.apache.juneau.cp.*;
 import org.apache.juneau.rest.annotation.*;
@@ -426,7 +426,7 @@ public class CallLogger {
 		}
 	}
 
-	private static final CallLoggerRule DEFAULT_RULE = CallLoggerRule.create(BasicBeanStore.INSTANCE).build();
+	private static final CallLoggerRule DEFAULT_RULE = CallLoggerRule.create(BasicBeanStore2.INSTANCE).build();
 
 	/**
 	 * System property name for the default logger name to use for {@link CallLogger} objects.
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/stats/MethodExecStore.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/stats/MethodExecStore.java
index f7b4b416a3..c03732c304 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/stats/MethodExecStore.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/stats/MethodExecStore.java
@@ -23,7 +23,7 @@ import java.util.*;
 import java.util.concurrent.*;
 
 import org.apache.juneau.*;
-import org.apache.juneau.commons.inject.BeanStore;
+import org.apache.juneau.commons.inject.*;
 import org.apache.juneau.cp.*;
 
 /**
@@ -119,7 +119,7 @@ public class MethodExecStore {
 	 * @return A new builder for this object.
 	 */
 	public static Builder create() {
-		return new Builder(BasicBeanStore.INSTANCE);
+		return new Builder(BasicBeanStore2.INSTANCE);
 	}
 
 	/**
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/stats/ThrownStore.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/stats/ThrownStore.java
index 6d29977fa6..d75b326233 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/stats/ThrownStore.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/stats/ThrownStore.java
@@ -25,7 +25,7 @@ import java.util.*;
 import java.util.concurrent.*;
 
 import org.apache.juneau.*;
-import org.apache.juneau.commons.inject.BeanStore;
+import org.apache.juneau.commons.inject.*;
 import org.apache.juneau.cp.*;
 
 /**
@@ -125,7 +125,7 @@ public class ThrownStore {
 	 * @return A new builder for this object.
 	 */
 	public static Builder create() {
-		return new Builder(BasicBeanStore.INSTANCE);
+		return new Builder(BasicBeanStore2.INSTANCE);
 	}
 
 	/**
@@ -148,7 +148,7 @@ public class ThrownStore {
 	 * Constructor.
 	 */
 	public ThrownStore() {
-		this(create(BasicBeanStore.INSTANCE));
+		this(create(BasicBeanStore2.INSTANCE));
 	}
 
 	/**
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/RestContext_Precedence_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/RestContext_Precedence_Test.java
index a901561f6a..6ccb0d2821 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/RestContext_Precedence_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/RestContext_Precedence_Test.java
@@ -23,7 +23,6 @@ import java.util.function.*;
 
 import org.apache.juneau.*;
 import org.apache.juneau.commons.inject.*;
-import org.apache.juneau.cp.*;
 import org.apache.juneau.rest.annotation.*;
 import org.apache.juneau.rest.logger.*;
 import org.apache.juneau.rest.mock.*;
@@ -62,8 +61,8 @@ class RestContext_Precedence_Test extends TestBase {
 	// Marker beans
 	//-----------------------------------------------------------------------------------------------------------------
 
-	private static final CallLogger SPRING_LOGGER = BasicCallLogger.create(BasicBeanStore.INSTANCE).build();
-	private static final CallLogger RESTINJECT_LOGGER = BasicCallLogger.create(BasicBeanStore.INSTANCE).build();
+	private static final CallLogger SPRING_LOGGER = BasicCallLogger.create(BasicBeanStore2.INSTANCE).build();
+	private static final CallLogger RESTINJECT_LOGGER = BasicCallLogger.create(BasicBeanStore2.INSTANCE).build();
 	private static final ThrownStore RESTINJECT_THROWN_STORE = ThrownStore.create().build();
 
 	//-----------------------------------------------------------------------------------------------------------------
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/Swagger_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/Swagger_Test.java
index 3949337233..dc1d1f9441 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/Swagger_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/Swagger_Test.java
@@ -28,6 +28,7 @@ import org.apache.juneau.annotation.*;
 import org.apache.juneau.commons.annotation.Schema;
 import org.apache.juneau.commons.annotation.ExternalDocs;
 import org.apache.juneau.commons.lang.*;
+import org.apache.juneau.commons.inject.*;
 import org.apache.juneau.cp.*;
 import org.apache.juneau.http.annotation.*;
 import org.apache.juneau.http.annotation.Tag;
@@ -73,7 +74,7 @@ class Swagger_Test extends TestBase {
 	public static class TestClasspathFileFinder extends BasicStaticFiles {
 
 		public TestClasspathFileFinder() {
-			super(StaticFiles.create(BasicBeanStore.INSTANCE).cp(Swagger_Test.class, null, false));
+			super(StaticFiles.create(BasicBeanStore2.INSTANCE).cp(Swagger_Test.class, null, false));
 		}
 
 		@Override /* FileFinder */
diff --git a/todo/TODO-15-replace-basicbeanstore-with-v2.md b/todo/TODO-15-replace-basicbeanstore-with-v2.md
index 8a38c90271..15cc5fb8e3 100644
--- a/todo/TODO-15-replace-basicbeanstore-with-v2.md
+++ b/todo/TODO-15-replace-basicbeanstore-with-v2.md
@@ -16,6 +16,8 @@ Eliminate the legacy injection stack in `org.apache.juneau.cp` (`BasicBeanStore`
 - ~~Phase 3 batch-3: drop vestigial `(BasicBeanStore)` casts at framework-defaults call sites~~ — **DONE (2026-05-08).** Sixteen `(BasicBeanStore) bs` casts in `RestContext.java` (lines 494, 515, 584, 676, 753, 768, 914, 937, 957, 987, 1008, 1029, 1064, 1110, 1125) and one in `RestOpContext.java` (line 437) dropped. These were vestigial leftovers from before the utility-class `create(...)` factories were widened to `WritableBeanStore` in the cascade-builder work. The cast was no longer r [...]
 - ~~Phase 3 batch-4: widen field types + getter return types in `RestSession` / `RestOpSession` / `VarResolver` / `VarResolverSession`~~ — **DONE (2026-05-08).** Field types and accessor return types widened from legacy `BasicBeanStore` to v2 `WritableBeanStore`; corresponding `BasicBeanStore.of((BasicBeanStore) X)` calls migrated to `new BasicBeanStore2(X)`: `VarResolver.beanStore` (field) + `VarResolver.createSession(BasicBeanStore)` (public method param) + `VarResolverSession.beanStor [...]
 - ~~Phase 3 batch-5: flip framework-default ctors + `init()` template methods to `BeanStore`; widen `BeanBuilder<T>` to `BeanStore`; unlock `RestContext.java:1199`~~ — **DONE (2026-05-08).** Constructor signatures and `init(...)` template method parameters of all framework defaults (`CallLogger`, `DebugEnablement`, `BasicCallLogger`, `BasicDebugEnablement`, `BasicTestCallLogger`, `BasicTestCaptureCallLogger`, `BasicDisabledCallLogger`, `BasicStaticFiles`, `BasicSwaggerProvider`) flipped  [...]
+- ~~Phase 3 batch-6: drop `@Rest(beanStore=X.class)` annotation, migrate Spring integration to v2, lock in `@RestInject > Spring > defaults` precedence~~ — **DONE (2026-05-08).** `SpringRestServlet.createBeanStore()` now returns `WritableBeanStore` and instantiates `SpringBeanStore2`. `RestContext.createBeanStore()` simplified to `new BasicBeanStore2(parentBs)` with optional `@RestInject WritableBeanStore` override (drops legacy `BasicBeanStore.create().overridingParent(...).build()` cha [...]
+- ~~Phase 3 batch-7: port `BasicBeanStore.INSTANCE` to v2 + migrate consumers~~ — **DONE (2026-05-08).** Added `BasicBeanStore2.INSTANCE` static field (typed as the concrete class for compatibility with `WritableBeanStore`-typed Builder ctors; documented as "treat as read-only"). Migrated 13 consumer references from `BasicBeanStore.INSTANCE` to `BasicBeanStore2.INSTANCE`: `BasicTestCaptureCallLogger`, `BasicCallLogger`, `CallLogger.DEFAULT_RULE`, `ThrownStore.create()` + parent-less ctor [...]
 
 ### Deeper blocker discovered (2026-05-08, batch 4)
 
@@ -110,10 +112,8 @@ Net new v2 surface from this decision: none. The `Builder` class simply goes awa
 
 ### Still to port (must be added to v2 before Phase 3 starts)
 
-- [ ] **`BasicBeanStore.INSTANCE`** — widely used as a shared read-only empty store (`SerializerSet`, `ParserSet`, `EncoderSet`, `SwaggerUI`, `OpenApiUI`, `ThrownStore`, several tests). Add a `BasicBeanStore2.INSTANCE` constant (or equivalent on `BeanStore`).
-- [ ] **`BasicBeanStore.Void.class`** — used as an annotation-default sentinel in `@Rest.beanStore()` and `RestAnnotation`. Either:
-  - port a `BasicBeanStore2.Void` sentinel class, or
-  - redesign those annotations (e.g., treat `BasicBeanStore2.class` itself as the sentinel and interpret "equal to default" as "unset").
+- ~~**`BasicBeanStore.INSTANCE`** — widely used as a shared read-only empty store (`SerializerSet`, `ParserSet`, `EncoderSet`, `SwaggerUI`, `OpenApiUI`, `ThrownStore`, several tests). Add a `BasicBeanStore2.INSTANCE` constant (or equivalent on `BeanStore`).~~ — **DONE (2026-05-08, batch-7).** Added `BasicBeanStore2.INSTANCE` (typed as the concrete class so it works for `WritableBeanStore`-typed Builder ctors; doc note says "treat as read-only"). 13 consumer references migrated. Legacy-cl [...]
+- ~~**`BasicBeanStore.Void.class`** — used as an annotation-default sentinel in `@Rest.beanStore()` and `RestAnnotation`.~~ — **MOOT (2026-05-08, batch-6).** `@Rest.beanStore()` removed entirely; the only remaining reference to `BasicBeanStore.Void` is inside `BeanStore_Test.java` exercising the legacy class itself, which dies with Phase 4. No v2 sentinel needed.
 - ~~**`BeanCreateMethodFinder` → v2 equivalent**~~ — **DONE.** Replaced by `BeanStore.createBeanFromMethod(Class<T>, Object, Predicate<MethodInfo>, Object...)`. The legacy DSL pattern:
   ```java
   new BeanCreateMethodFinder<>(Type.class, resource, beanStore)