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 <[email protected]> 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 <[email protected]> --- .../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 — 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 — 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)
