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 48621576d7d260a0c2ce5d82540d82616dea6f43
Author: James Bognar <[email protected]>
AuthorDate: Wed May 13 08:04:05 2026 -0400

    refactor: widen public getters + introduce BeanTypeResolver SPI + flip 
JsonList to ArrayList (TODO-5 Step 8b-ii Phase C tasks 1/2/4)
    
    Co-authored-by: Cursor <[email protected]>
---
 .../juneau/commons/bean/BeanTypeResolver.java      | 68 ++++++++++++++++++++++
 .../apache/juneau/jena/RdfBeanPropertyMeta.java    |  8 ++-
 .../org/apache/juneau/jena/RdfParserSession.java   |  2 +-
 .../apache/juneau/jena/RdfSerializerSession.java   |  2 +-
 .../apache/juneau/jena/RdfStreamParserSession.java |  2 +-
 .../juneau/jena/RdfStreamSerializerSession.java    |  2 +-
 .../src/main/java/org/apache/juneau/BeanMap.java   |  4 +-
 .../src/main/java/org/apache/juneau/BeanMeta.java  | 21 +++++--
 .../java/org/apache/juneau/BeanPropertyMeta.java   | 27 +++++----
 .../java/org/apache/juneau/BeanPropertyValue.java  |  2 +-
 .../src/main/java/org/apache/juneau/ClassMeta.java |  2 +-
 .../java/org/apache/juneau/MarshallingContext.java | 17 +++++-
 .../org/apache/juneau/bson/BsonParserSession.java  |  5 +-
 .../org/apache/juneau/cbor/CborParserSession.java  |  2 +-
 .../org/apache/juneau/collections/JsonMap.java     |  2 +-
 .../org/apache/juneau/csv/CsvParserSession.java    |  2 +-
 .../apache/juneau/hjson/HjsonParserSession.java    |  6 +-
 .../juneau/hjson/HjsonSerializerSession.java       |  2 +-
 .../apache/juneau/hocon/HoconParserSession.java    |  6 +-
 .../juneau/hocon/HoconSerializerSession.java       |  2 +-
 .../org/apache/juneau/html/HtmlParserSession.java  |  4 +-
 .../apache/juneau/html/HtmlSerializerSession.java  | 11 ++--
 .../org/apache/juneau/ini/IniParserSession.java    |  4 +-
 .../apache/juneau/ini/IniSerializerSession.java    |  8 +--
 .../apache/juneau/jcs/JcsSerializerSession.java    |  4 +-
 .../org/apache/juneau/json/JsonParserSession.java  | 22 +++----
 .../apache/juneau/json/JsonSerializerSession.java  |  2 +-
 .../jsonschema/JsonSchemaGeneratorSession.java     |  2 +-
 .../juneau/markdown/MarkdownDocParserSession.java  |  4 +-
 .../juneau/markdown/MarkdownParserSession.java     |  7 ++-
 .../juneau/msgpack/MsgPackParserSession.java       |  2 +-
 .../org/apache/juneau/objecttools/ObjectRest.java  |  2 +-
 .../juneau/parquet/ParquetParserSession.java       |  4 +-
 .../juneau/parquet/ParquetSchemaBuilder.java       |  2 +-
 .../org/apache/juneau/parser/ParserSession.java    |  7 ++-
 .../apache/juneau/proto/ProtoParserSession.java    |  4 +-
 .../juneau/proto/ProtoSerializerSession.java       |  4 +-
 .../org/apache/juneau/toml/TomlParserSession.java  |  2 +-
 .../apache/juneau/toml/TomlSerializerSession.java  | 12 ++--
 .../org/apache/juneau/uon/UonParserSession.java    |  8 +--
 .../apache/juneau/uon/UonSerializerSession.java    |  2 +-
 .../urlencoding/UrlEncodingParserSession.java      | 14 ++---
 .../urlencoding/UrlEncodingSerializerSession.java  |  6 +-
 .../java/org/apache/juneau/xml/XmlBeanMeta.java    |  9 +--
 .../org/apache/juneau/xml/XmlBeanPropertyMeta.java | 14 ++---
 .../org/apache/juneau/xml/XmlParserSession.java    |  8 +--
 .../org/apache/juneau/yaml/YamlParserSession.java  | 10 ++--
 .../apache/juneau/yaml/YamlSerializerSession.java  |  2 +-
 .../apache/juneau/rest/beans/BeanDescription.java  |  2 +-
 .../test/java/org/apache/juneau/BeanMap_Test.java  |  6 +-
 todo/TODO-5-bean-runtime-types-to-commons.md       | 22 +++++--
 51 files changed, 255 insertions(+), 139 deletions(-)

diff --git 
a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/bean/BeanTypeResolver.java
 
b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/bean/BeanTypeResolver.java
new file mode 100644
index 0000000000..2c4d48371d
--- /dev/null
+++ 
b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/bean/BeanTypeResolver.java
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.juneau.commons.bean;
+
+import org.apache.juneau.commons.reflect.AnnotationInfo;
+import org.apache.juneau.commons.reflect.AnnotationProvider;
+import org.apache.juneau.commons.reflect.ClassInfo;
+import org.apache.juneau.commons.reflect.TypeVariables;
+
+/**
+ * Bean-modeling SPI seam that exposes the type-resolution operations the 
bean-property
+ * validation pass needs from the marshalling layer.
+ *
+ * <p>
+ * Implemented by the marshalling-side {@code MarshallingContext} so that
+ * {@code BeanPropertyMeta.Builder#validate} can stay free of direct
+ * {@code MarshallingContext} references and live in {@code 
org.apache.juneau.commons.bean}.
+ *
+ * <p>
+ * The {@code Object}-typed counterpart on the {@code Builder} is what gets 
stored long-term;
+ * {@code validate(...)} narrows it to {@link BeanTypeResolver} just for the 
duration of the
+ * resolve+validate pass.
+ *
+ * @see BeanTypeInfo
+ */
+public interface BeanTypeResolver {
+
+       /**
+        * Resolves the bean-property type-info for a property given its 
(optional)
+        * {@link BeanProp @BeanProp} annotation and Java type.
+        *
+        * @param lastBeanProp The last {@link BeanProp @BeanProp} annotation 
found on the property's
+        *      field/getter/setter, or {@code null} if none.
+        * @param type The Java type of the property as derived from the 
field/getter/setter signature.
+        * @param typeVarImpls Resolved type-variable substitutions for the 
enclosing class.
+        * @return The resolved type-info, or {@code null} if no resolution was 
possible.
+        */
+       BeanTypeInfo<?> resolveType(AnnotationInfo<BeanProp> lastBeanProp, 
ClassInfo type, TypeVariables typeVarImpls);
+
+       /**
+        * Returns the type-info for {@code Object.class} (used as the fallback 
element/value type for
+        * raw/unparameterized collections and maps).
+        *
+        * @return Non-{@code null} type-info for {@code Object.class}.
+        */
+       BeanTypeInfo<?> objectType();
+
+       /**
+        * Returns the annotation provider used to read annotations during 
property validation.
+        *
+        * @return Non-{@code null} annotation provider.
+        */
+       AnnotationProvider getAnnotationProvider();
+}
diff --git 
a/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfBeanPropertyMeta.java
 
b/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfBeanPropertyMeta.java
index 53ef2c4adb..61954dc0fb 100644
--- 
a/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfBeanPropertyMeta.java
+++ 
b/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfBeanPropertyMeta.java
@@ -53,13 +53,15 @@ public class RdfBeanPropertyMeta extends 
ExtendedBeanPropertyMeta {
        public RdfBeanPropertyMeta(BeanPropertyMeta bpm, RdfMetaProvider mp) {
                super(bpm);
 
-               var ap = 
bpm.getClassMeta().getMarshallingContext().getAnnotationProvider();
+               var bpmcm = (ClassMeta<?>) bpm.getClassMeta();
+               var bmcm = (ClassMeta<?>) bpm.getBeanMeta().getClassMeta();
+               var ap = bpmcm.getMarshallingContext().getAnnotationProvider();
                var rdfs = new MultiList<>(
-                       rstream(ap.find(Rdf.class, 
bpm.getBeanMeta().getClassMeta())).map(AnnotationInfo::inner).toList(),
+                       rstream(ap.find(Rdf.class, 
bmcm)).map(AnnotationInfo::inner).toList(),
                        
reverse(bpm.getAnnotations(Rdf.class).map(AnnotationInfo::inner).toList())
                );
                var schemas = new MultiList<>(
-                       rstream(ap.find(RdfSchema.class, 
bpm.getBeanMeta().getClassMeta())).map(AnnotationInfo::inner).toList(),
+                       rstream(ap.find(RdfSchema.class, 
bmcm)).map(AnnotationInfo::inner).toList(),
                        
reverse(bpm.getAnnotations(RdfSchema.class).map(AnnotationInfo::inner).toList())
                );
 
diff --git 
a/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfParserSession.java
 
b/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfParserSession.java
index 53c6638c8e..ce903f33c0 100644
--- 
a/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfParserSession.java
+++ 
b/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfParserSession.java
@@ -487,7 +487,7 @@ public class RdfParserSession extends ReaderParserSession {
                        setCurrentProperty(pMeta);
                        if (nn(pMeta)) {
                                var o = st.getObject();
-                               var cm = pMeta.getClassMeta();
+                               var cm = (ClassMeta<?>) pMeta.getClassMeta();
                                if (cm.isCollectionOrArray() && 
isMultiValuedCollections(pMeta)) {
                                        var et = cm.getElementType();
                                        var value = parseAnything(et, o, 
m.getBean(false), pMeta);
diff --git 
a/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfSerializerSession.java
 
b/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfSerializerSession.java
index b0e5a6ae93..dc99399234 100644
--- 
a/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfSerializerSession.java
+++ 
b/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfSerializerSession.java
@@ -466,7 +466,7 @@ public class RdfSerializerSession extends 
WriterSerializerSession {
                Collections.reverse(l);
                l.forEach(x -> {
                        var bpMeta = x.getMeta();
-                       var cMeta = bpMeta.getClassMeta();
+                       var cMeta = (ClassMeta<?>) bpMeta.getClassMeta();
                        var bpRdf = getRdfBeanPropertyMeta(bpMeta);
                        var bpXml = getXmlBeanPropertyMeta(bpMeta);
 
diff --git 
a/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfStreamParserSession.java
 
b/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfStreamParserSession.java
index 8a55e2e1b2..2f305ebd8d 100644
--- 
a/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfStreamParserSession.java
+++ 
b/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfStreamParserSession.java
@@ -479,7 +479,7 @@ public class RdfStreamParserSession extends 
InputStreamParserSession {
                        setCurrentProperty(pMeta);
                        if (nn(pMeta)) {
                                var o = st.getObject();
-                               var cm = pMeta.getClassMeta();
+                               var cm = (ClassMeta<?>) pMeta.getClassMeta();
                                if (cm.isCollectionOrArray() && 
isMultiValuedCollections(pMeta)) {
                                        var et = cm.getElementType();
                                        var value = parseAnything(et, o, 
m.getBean(false), pMeta);
diff --git 
a/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfStreamSerializerSession.java
 
b/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfStreamSerializerSession.java
index e6ad4d09a1..c803c828f6 100644
--- 
a/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfStreamSerializerSession.java
+++ 
b/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfStreamSerializerSession.java
@@ -385,7 +385,7 @@ public class RdfStreamSerializerSession extends 
OutputStreamSerializerSession {
                Collections.reverse(l);
                l.forEach(x -> {
                        var bpMeta = x.getMeta();
-                       var cMeta = bpMeta.getClassMeta();
+                       var cMeta = (ClassMeta<?>) bpMeta.getClassMeta();
                        var bpRdf = getRdfBeanPropertyMeta(bpMeta);
                        var bpXml = getXmlBeanPropertyMeta(bpMeta);
                        if (bpRdf.isBeanUri())
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanMap.java 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanMap.java
index 226e12adc9..aee7aa8f68 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanMap.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanMap.java
@@ -506,12 +506,12 @@ public class BeanMap<T> extends 
AbstractMap<String,Object> implements Delegate<T
        public final MarshallingSession getMarshallingSession() { return 
session; }
 
        /**
-        * Returns the {@link ClassMeta} of the wrapped bean.
+        * Returns the {@link BeanTypeInfo} of the wrapped bean.
         *
         * @return The class type of the wrapped bean.
         */
        @Override /* Overridden from Delegate */
-       public ClassMeta<T> getClassMeta() { return this.meta.getClassMeta(); }
+       public BeanTypeInfo<T> getClassMeta() { return 
this.meta.getClassMeta(); }
 
        /**
         * Returns the metadata associated with this bean map.
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanMeta.java 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanMeta.java
index a85d3577b9..ae900b20f8 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanMeta.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanMeta.java
@@ -837,9 +837,14 @@ public class BeanMeta<T> {
         * The bean registry is used to resolve dictionary names to class 
types. It's created when a bean class has a
         * {@link Bean#dictionary() @Marshalled(dictionary)} annotation that 
specifies a list of possible subclasses.
         *
+        * <p>
+        * Returns the bean-modeling-side SPI type ({@link 
BeanRegistryLookup}).  Marshalling-side callers that need
+        * the full {@link BeanRegistry} surface (e.g. {@code 
getClassMeta(String)}) cast at the call site — the
+        * concrete instance in-tree is always a {@link BeanRegistry}.
+        *
         * @return The bean registry for this bean, or <jk>null</jk> if no bean 
registry is associated with it.
         */
-       public BeanRegistry getBeanRegistry() { return (BeanRegistry) 
beanRegistry.get(); }
+       public BeanRegistryLookup getBeanRegistry() { return 
beanRegistry.get(); }
 
        /**
         * Returns the per-property {@link BeanRegistry} associated with the 
given {@link BeanPropertyMeta}.
@@ -863,21 +868,25 @@ public class BeanMeta<T> {
         * @return The bean registry for the specified property, or 
<jk>null</jk> if none was registered (e.g. the property
         *      belongs to a different bean meta).
         */
-       public BeanRegistry getPropertyBeanRegistry(BeanPropertyMeta p) {
-               return (BeanRegistry) propertyBeanRegistries.get(p);
+       public BeanRegistryLookup getPropertyBeanRegistry(BeanPropertyMeta p) {
+               return propertyBeanRegistries.get(p);
        }
 
        /**
-        * Returns the {@link ClassMeta} of this bean.
+        * Returns the {@link BeanTypeInfo} of this bean.
         *
         * <p>
         * Returns <jk>null</jk> when this {@link BeanMeta} was constructed via 
the commons-side path
         * ({@link #of(Class, BeanConfigContext)}) — in that case {@link 
#getClassInfo()} carries the
         * pure-reflection view of the bean class.
         *
-        * @return The {@link ClassMeta} of this bean, or <jk>null</jk> for 
bean-modeling-only construction.
+        * <p>
+        * Returns the bean-modeling-side SPI type ({@link BeanTypeInfo}).  
Marshalling-side callers that need
+        * the {@link ClassMeta} narrowing must cast — the concrete instance 
in-tree is always a {@link ClassMeta}.
+        *
+        * @return The {@link BeanTypeInfo} of this bean, or <jk>null</jk> for 
bean-modeling-only construction.
         */
-       public ClassMeta<T> getClassMeta() { return (ClassMeta<T>) classMeta; }
+       public BeanTypeInfo<T> getClassMeta() { return classMeta; }
 
        /**
         * Returns the {@link ClassInfo} of this bean.
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanPropertyMeta.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanPropertyMeta.java
index f56a3b2a45..fe365128a6 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanPropertyMeta.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanPropertyMeta.java
@@ -339,7 +339,7 @@ public class BeanPropertyMeta implements 
Comparable<BeanPropertyMeta> {
                        "java:S112",  // Generic exception thrown; acceptable 
for framework/lifecycle methods
                        "java:S6541"  // Brain Method: validate() intentionally 
consolidates property metadata resolution
                })
-               public boolean validate(MarshallingContext bc, TypeVariables 
typeVarImpls, Set<String> bpro, Set<String> bpwo) throws Exception {
+               public boolean validate(BeanTypeResolver bc, TypeVariables 
typeVarImpls, Set<String> bpro, Set<String> bpwo) throws Exception {
 
                        var ap = nn(bc) ? bc.getAnnotationProvider() : 
config.getAnnotationProvider();
 
@@ -368,7 +368,7 @@ public class BeanPropertyMeta implements 
Comparable<BeanPropertyMeta> {
                                if (nn(bc) && (nn(field) || ne(lbp))) {
                                        // Only use field type if it's a bean 
property or has @BeanProp annotation.
                                        // Otherwise, we want to infer the type 
from the getter or setter.
-                                       rawTypeMeta = 
bc.resolveClassMeta(opt(last(lbp)).orElse(null), innerField.getFieldType(), 
typeVarImpls);
+                                       rawTypeMeta = 
bc.resolveType(opt(last(lbp)).orElse(null), innerField.getFieldType(), 
typeVarImpls);
                                        isUri |= (rawTypeMeta.isUri());
                                }
                                lbp.forEach(x -> {
@@ -384,7 +384,7 @@ public class BeanPropertyMeta implements 
Comparable<BeanPropertyMeta> {
                        if (nn(getter)) {
                                var lbp = ap.find(BeanProp.class, gi);
                                if (nn(bc) && rawTypeMeta == null)
-                                       rawTypeMeta = 
bc.resolveClassMeta(opt(last(lbp)).orElse(null), getter.getReturnType(), 
typeVarImpls);
+                                       rawTypeMeta = 
bc.resolveType(opt(last(lbp)).orElse(null), getter.getReturnType(), 
typeVarImpls);
                                if (nn(rawTypeMeta))
                                        isUri |= rawTypeMeta.isUri();
                                isUri |= ap.has(Uri.class, gi);
@@ -400,7 +400,7 @@ public class BeanPropertyMeta implements 
Comparable<BeanPropertyMeta> {
                        if (nn(setter)) {
                                var lbp = ap.find(BeanProp.class, si);
                                if (nn(bc) && rawTypeMeta == null)
-                                       rawTypeMeta = 
bc.resolveClassMeta(opt(last(lbp)).orElse(null), 
setter.getParameterTypes().get(0), typeVarImpls);
+                                       rawTypeMeta = 
bc.resolveType(opt(last(lbp)).orElse(null), setter.getParameterTypes().get(0), 
typeVarImpls);
                                if (nn(rawTypeMeta))
                                        isUri |= rawTypeMeta.isUri();
                                isUri |= ap.has(Uri.class, si);
@@ -465,12 +465,12 @@ public class BeanPropertyMeta implements 
Comparable<BeanPropertyMeta> {
                                if (isDyna) {
                                        rawTypeMeta = 
rawTypeMeta.getValueType();
                                        if (rawTypeMeta == null && nn(bc))
-                                               rawTypeMeta = bc.object();
+                                               rawTypeMeta = bc.objectType();
                                }
 
                                if (typeMeta == null) {
                                        if (rawTypeMeta == null && nn(bc))
-                                               typeMeta = bc.object();
+                                               typeMeta = bc.objectType();
                                        else
                                                typeMeta = rawTypeMeta;
                                }
@@ -890,10 +890,10 @@ public class BeanPropertyMeta implements 
Comparable<BeanPropertyMeta> {
         *
         * @return The bean dictionary in use for this bean property.  Never 
<jk>null</jk>.
         */
-       public BeanRegistry getBeanRegistry() { return 
beanMeta.getPropertyBeanRegistry(this); }
+       public BeanRegistry getBeanRegistry() { return (BeanRegistry) 
beanMeta.getPropertyBeanRegistry(this); }
 
        /**
-        * Returns the {@link ClassMeta} of the class of this property.
+        * Returns the {@link BeanTypeInfo} of the class of this property.
         *
         * <p>
         * If this property or the property type class has a {@link ObjectSwap} 
associated with it, this method returns the
@@ -901,9 +901,14 @@ public class BeanPropertyMeta implements 
Comparable<BeanPropertyMeta> {
         * This matches the class type that is used by the {@link 
#get(BeanMap,String)} and
         * {@link #set(BeanMap,String,Object)} methods.
         *
-        * @return The {@link ClassMeta} of the class of this property.
+        * <p>
+        * Returns the bean-modeling-side SPI type ({@link BeanTypeInfo}).  
Marshalling-side callers that need the
+        * {@link ClassMeta} narrowing must cast — the concrete instance 
in-tree is always a {@link ClassMeta}.
+        *
+        * @return The {@link BeanTypeInfo} of the class of this property, or 
<jk>null</jk> if this property was built via
+        *      the bean-modeling-only path.
         */
-       public ClassMeta<?> getClassMeta() { return (ClassMeta<?>) typeMeta; }
+       public BeanTypeInfo<?> getClassMeta() { return typeMeta; }
 
        /**
         * Returns the metadata on the property that this metadata is a 
delegate for.
@@ -1217,7 +1222,7 @@ public class BeanPropertyMeta implements 
Comparable<BeanPropertyMeta> {
 
                                                if 
(propertyClass.isInstance(valueList) || (nn(setter) && 
setter.getParameterTypes().get(0).is(Collection.class))) {
                                                        if (! 
elementType.isObject()) {
-                                                               var l = new 
JsonList(valueList);
+                                                               var l = new 
ArrayList<>(valueList);
                                                                for (var i = 
l.listIterator(); i.hasNext();) {
                                                                        var v = 
i.next();
                                                                        var 
needsConversion = v == null ? elementType.isOptional() : ! 
elementType.isInstance(v);
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanPropertyValue.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanPropertyValue.java
index 73c775c864..2416d256e8 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanPropertyValue.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanPropertyValue.java
@@ -75,7 +75,7 @@ public class BeanPropertyValue implements 
Comparable<BeanPropertyValue> {
         *
         * @return The bean property metadata.
         */
-       public final ClassMeta<?> getClassMeta() { return pMeta.getClassMeta(); 
}
+       public final ClassMeta<?> getClassMeta() { return (ClassMeta<?>) 
pMeta.getClassMeta(); }
 
        /**
         * Returns the bean property metadata.
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/ClassMeta.java 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/ClassMeta.java
index f05140c218..e599ae73a5 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/ClassMeta.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/ClassMeta.java
@@ -496,7 +496,7 @@ public class ClassMeta<T> extends BeanTypeInfo<T> {
         * @return The bean registry for this class, or <jk>null</jk> if no 
bean registry is associated with it.
         */
        public BeanRegistry getBeanRegistry() {
-               return beanMeta.get().optBeanMeta().map(x -> 
x.getBeanRegistry()).orElse(null);
+               return beanMeta.get().optBeanMeta().map(x -> (BeanRegistry) 
x.getBeanRegistry()).orElse(null);
        }
 
        /**
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/MarshallingContext.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/MarshallingContext.java
index be8e32c3f0..701cf8a0f8 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/MarshallingContext.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/MarshallingContext.java
@@ -174,7 +174,7 @@ import org.apache.juneau.commons.bean.*;
        "java:S1452", // Wildcard required - ClassMeta<?> for parameter 
resolution and type variables
        "java:S1612"  // Lambdas used instead of method references for 
readability in complex chained expressions
 })
-public class MarshallingContext extends Context implements ConversionFinder {
+public class MarshallingContext extends Context implements ConversionFinder, 
org.apache.juneau.commons.bean.BeanTypeResolver {
 
        // Property name constants
        private static final String PROP_beanClassVisibility = 
"beanClassVisibility";
@@ -4869,6 +4869,21 @@ public class MarshallingContext extends Context 
implements ConversionFinder {
                return cmObject;
        }
 
+       
//-----------------------------------------------------------------------------------------------------------------
+       // BeanTypeResolver implementation — bridges the marshalling-side 
ClassMeta resolution into the bean-modeling
+       // SPI seam that BeanPropertyMeta.Builder.validate() consumes.
+       
//-----------------------------------------------------------------------------------------------------------------
+
+       @Override /* Overridden from BeanTypeResolver */
+       public org.apache.juneau.commons.bean.BeanTypeInfo<?> 
resolveType(AnnotationInfo<org.apache.juneau.commons.bean.BeanProp> 
lastBeanProp, ClassInfo type, TypeVariables typeVarImpls) {
+               return resolveClassMeta(lastBeanProp, type, typeVarImpls);
+       }
+
+       @Override /* Overridden from BeanTypeResolver */
+       public org.apache.juneau.commons.bean.BeanTypeInfo<?> objectType() {
+               return cmObject;
+       }
+
        @Override /* Overridden from Context */
        protected FluentMap<String,Object> properties() {
                return super.properties()
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/bson/BsonParserSession.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/bson/BsonParserSession.java
index 246518b4ec..8479381d56 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/bson/BsonParserSession.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/bson/BsonParserSession.java
@@ -178,8 +178,9 @@ public class BsonParserSession extends 
InputStreamParserSession {
                                        if (nn(value))
                                                beanMap = 
applyTypeProperty(beanMap, value.toString(), eType);
                                } else if (bpm != null) {
-                                       value = readTypedValue(is, et, 
bpm.getClassMeta(), beanMap.getBean(false), bpm);
-                                       setName(bpm.getClassMeta(), value, key);
+                                       var bcm = (ClassMeta<?>) 
bpm.getClassMeta();
+                                       value = readTypedValue(is, et, bcm, 
beanMap.getBean(false), bpm);
+                                       setName(bcm, value, key);
                                        try {
                                                bpm.set(beanMap, key, value);
                                        } catch (BeanRuntimeException e) {
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/cbor/CborParserSession.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/cbor/CborParserSession.java
index 244511ea1d..30f02df825 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/cbor/CborParserSession.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/cbor/CborParserSession.java
@@ -276,7 +276,7 @@ public class CborParserSession extends 
InputStreamParserSession {
                                                        else
                                                                
onUnknownProperty(pName, m, parseAnything(string(), is, null, null));
                                                } else {
-                                                       var cm = 
bpm.getClassMeta();
+                                                       var cm = (ClassMeta<?>) 
bpm.getClassMeta();
                                                        Object value = 
parseAnything(cm, is, m.getBean(false), bpm);
                                                        setName(cm, value, 
pName);
                                                        try {
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/collections/JsonMap.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/collections/JsonMap.java
index 271af569b9..0f7e5696f1 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/collections/JsonMap.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/collections/JsonMap.java
@@ -1875,7 +1875,7 @@ public class JsonMap extends LinkedHashMap<String,Object> 
{
 
                                                // Attempt to recursively cast 
child maps.
                                                if (v instanceof JsonMap v2)
-                                                       v = 
v2.cast(bm.getProperty(k).getMeta().getClassMeta());
+                                                       v = 
v2.cast((ClassMeta<?>) bm.getProperty(k).getMeta().getClassMeta());
 
                                                bm.put(k, v);
                                        }
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/csv/CsvParserSession.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/csv/CsvParserSession.java
index 28dc07e1fa..8dc164a999 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/csv/CsvParserSession.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/csv/CsvParserSession.java
@@ -379,7 +379,7 @@ public class CsvParserSession extends ReaderParserSession {
                        var pm = m.getPropertyMeta(header);
                        if (pm != null) {
                                setCurrentProperty(pm);
-                               var converted = parseCellValue(val, 
pm.getClassMeta());
+                               var converted = parseCellValue(val, 
(ClassMeta<?>) pm.getClassMeta());
                                pm.set(m, header, converted);
                                setCurrentProperty(null);
                        } else {
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/hjson/HjsonParserSession.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/hjson/HjsonParserSession.java
index d2f8d7c0ce..e012a26a9a 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/hjson/HjsonParserSession.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/hjson/HjsonParserSession.java
@@ -256,13 +256,13 @@ public class HjsonParserSession extends 
ReaderParserSession {
                        var val = (pm == null) ? null : getBeanValueSafely(bm, 
key);
                        if (pm == null || val == null)
                                continue;
-                       var cm = pm.getClassMeta();
+                       var cm = (ClassMeta<?>) pm.getClassMeta();
                        if (cm.getNameProperty() != null)
                                setName(cm, val, key);
                        if (cm.getParentProperty() != null)
                                setParent(cm, val, bean);
-                       if (cm.isMap() && val instanceof Map<?,?> val2 && 
!cm.getValueType().isObject() && cm.getValueType().getNameProperty() != null) {
-                               var valueType = cm.getValueType();
+                       if (cm.isMap() && val instanceof Map<?,?> val2 && 
!cm.getValueType().isObject() && ((ClassMeta<?>) 
cm.getValueType()).getNameProperty() != null) {
+                               var valueType = (ClassMeta<?>) 
cm.getValueType();
                                for (Map.Entry<?, ?> e : 
((Map<?,?>)val2).entrySet())
                                        setName(valueType, e.getValue(), 
e.getKey());
                        }
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/hjson/HjsonSerializerSession.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/hjson/HjsonSerializerSession.java
index 4c99cd39f7..d5a691e361 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/hjson/HjsonSerializerSession.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/hjson/HjsonSerializerSession.java
@@ -128,7 +128,7 @@ public class HjsonSerializerSession extends 
WriterSerializerSession {
                }
 
                m.forEachValue(checkNull, (pMeta, key, value, thrown) -> {
-                       var cMeta = pMeta.getClassMeta();
+                       var cMeta = (ClassMeta<?>) pMeta.getClassMeta();
                        if (nn(thrown))
                                onBeanGetterException(pMeta, thrown);
                        if (canIgnoreValue(cMeta, key, value))
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/hocon/HoconParserSession.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/hocon/HoconParserSession.java
index f234ff8f1c..eeba3ef282 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/hocon/HoconParserSession.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/hocon/HoconParserSession.java
@@ -438,13 +438,13 @@ public class HoconParserSession extends 
ReaderParserSession {
                        var val = pm == null ? null : getBeanValueSafely(bm, 
key);
                        if (pm == null || val == null)
                                continue;
-                       var cm = pm.getClassMeta();
+                       var cm = (ClassMeta<?>) pm.getClassMeta();
                        if (cm.getNameProperty() != null)
                                setName(cm, val, key);
                        if (cm.getParentProperty() != null)
                                setParent(cm, val, bean);
-                       if (cm.isMap() && val instanceof Map<?, ?> val2 && 
!cm.getValueType().isObject() && cm.getValueType().getNameProperty() != null) {
-                               var valueType = cm.getValueType();
+                       if (cm.isMap() && val instanceof Map<?, ?> val2 && 
!cm.getValueType().isObject() && ((ClassMeta<?>) 
cm.getValueType()).getNameProperty() != null) {
+                               var valueType = (ClassMeta<?>) 
cm.getValueType();
                                for (Map.Entry<?, ?> e : ((Map<?, ?>) 
val2).entrySet())
                                        setName(valueType, e.getValue(), 
e.getKey());
                        }
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/hocon/HoconSerializerSession.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/hocon/HoconSerializerSession.java
index feb7f7708e..7f7bed1e4b 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/hocon/HoconSerializerSession.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/hocon/HoconSerializerSession.java
@@ -130,7 +130,7 @@ public class HoconSerializerSession extends 
WriterSerializerSession {
                }
 
                m.forEachValue(checkNull, (pMeta, key, value, thrown) -> {
-                       var cMeta = pMeta.getClassMeta();
+                       var cMeta = (ClassMeta<?>) pMeta.getClassMeta();
                        if (nn(thrown))
                                onBeanGetterException(pMeta, thrown);
                        if (canIgnoreValue(cMeta, key, value))
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlParserSession.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlParserSession.java
index d09e8c4753..a401be1af6 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlParserSession.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlParserSession.java
@@ -511,7 +511,7 @@ public class HtmlParserSession extends XmlParserSession {
                                if (pMeta == null) {
                                        onUnknownProperty(key, m, 
parseAnything(object(), r, null, false, null));
                                } else {
-                                       var cm = pMeta.getClassMeta();
+                                       var cm = (ClassMeta<?>) 
pMeta.getClassMeta();
                                        Object value = parseAnything(cm, r, 
m.getBean(false), false, pMeta);
                                        setName(cm, value, key);
                                        try {
@@ -648,7 +648,7 @@ public class HtmlParserSession extends XmlParserSession {
                                                parseAnything(object(), r, l, 
false, null);
                                        } else {
                                                BeanPropertyMeta bpm = 
e.getMeta();
-                                               var cm = bpm.getClassMeta();
+                                               var cm = (ClassMeta<?>) 
bpm.getClassMeta();
                                                Object value = 
parseAnything(cm, r, m.getBean(false), false, bpm);
                                                setName(cm, value, key);
                                                bpm.set(m, key, value);
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlSerializerSession.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlSerializerSession.java
index 36eabf0cac..1bb200f734 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlSerializerSession.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlSerializerSession.java
@@ -523,7 +523,8 @@ public class HtmlSerializerSession extends 
XmlSerializerSession {
        })
        private void serializeBeanMap(XmlWriter out, BeanMap<?> m, ClassMeta<?> 
eType, BeanPropertyMeta ppMeta) throws SerializeException {
 
-               HtmlClassMeta cHtml = getHtmlClassMeta(m.getClassMeta());
+               var mcm = (ClassMeta<?>) m.getClassMeta();
+               HtmlClassMeta cHtml = getHtmlClassMeta(mcm);
                HtmlBeanPropertyMeta bpHtml = getHtmlBeanPropertyMeta(ppMeta);
 
                int i = indent;
@@ -531,8 +532,8 @@ public class HtmlSerializerSession extends 
XmlSerializerSession {
                out.oTag(i, TAG_table);
 
                String typeName = m.getMeta().getDictionaryName();
-               if (nn(typeName) && eType != m.getClassMeta())
-                       out.attr(getBeanTypePropertyName(m.getClassMeta()), 
typeName);
+               if (nn(typeName) && eType != mcm)
+                       out.attr(getBeanTypePropertyName(mcm), typeName);
 
                out.w('>').nl(i);
                if (isAddKeyValueTableHeaders() && ! (cHtml.isNoTableHeaders() 
|| bpHtml.isNoTableHeaders())) {
@@ -545,7 +546,7 @@ public class HtmlSerializerSession extends 
XmlSerializerSession {
                Predicate<Object> checkNull = x -> isKeepNullProperties() || 
nn(x);
 
                m.forEachValue(checkNull, (pMeta, key, value, thrown) -> {
-                       var cMeta = pMeta.getClassMeta();
+                       var cMeta = (ClassMeta<?>) pMeta.getClassMeta();
 
                        if (nn(thrown))
                                onBeanGetterException(pMeta, thrown);
@@ -710,7 +711,7 @@ public class HtmlSerializerSession extends 
XmlSerializerSession {
                                                        out.cTag();
                                                        if (nn(link))
                                                                
out.oTag("a").attrUri("href", link).cTag();
-                                                       ContentResult cr = 
serializeAnything(out, value, pMeta.getClassMeta(), p.getKey(), pMeta, 2, 
false, true);
+                                                       ContentResult cr = 
serializeAnything(out, value, (ClassMeta<?>) pMeta.getClassMeta(), p.getKey(), 
pMeta, 2, false, true);
                                                        if (cr == CR_ELEMENTS)
                                                                out.i(i + 2);
                                                        if (nn(link))
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/ini/IniParserSession.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/ini/IniParserSession.java
index 2a1c884285..11cb514dff 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/ini/IniParserSession.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/ini/IniParserSession.java
@@ -144,7 +144,7 @@ public class IniParserSession extends ReaderParserSession {
                                        continue;
                                if (pMeta == null)
                                        throw new ParseException(this, "Unknown 
property ''{0}''", key);
-                               var value = parseValue(rawValue, 
pMeta.getClassMeta());
+                               var value = parseValue(rawValue, (ClassMeta<?>) 
pMeta.getClassMeta());
                                bm.put(key, value);
                        }
                }
@@ -165,7 +165,7 @@ public class IniParserSession extends ReaderParserSession {
                                continue;
                        if (pMeta == null)
                                continue;
-                       var cMeta = pMeta.getClassMeta();
+                       var cMeta = (ClassMeta<?>) pMeta.getClassMeta();
                        var childPath = sectionPath.isEmpty() ? childName : 
sectionPath + SECTION_PATH_DELIMITER + childName;
                        if (cMeta.isBean()) {
                                var child = 
toBeanMap(cMeta.newInstance(getOuter()));
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/ini/IniSerializerSession.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/ini/IniSerializerSession.java
index 63c4038d3c..080ee15dd3 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/ini/IniSerializerSession.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/ini/IniSerializerSession.java
@@ -119,9 +119,9 @@ public class IniSerializerSession extends 
WriterSerializerSession {
                m.forEachValue(checkNull, (pMeta, key, value, thrown) -> {
                        if (nn(thrown))
                                onBeanGetterException(pMeta, thrown);
-                       if (canIgnoreValue(pMeta.getClassMeta(), key, value))
+                       var cMeta = (ClassMeta<?>) pMeta.getClassMeta();
+                       if (canIgnoreValue(cMeta, key, value))
                                return;
-                       var cMeta = pMeta.getClassMeta();
                        var aType = value == null ? cMeta : 
getClassMetaForObject(value, cMeta);
                        var iniMeta = ctx.getIniBeanPropertyMeta(pMeta);
                        // Collections/arrays are written as inline key-value 
(not sections), so they must appear in
@@ -151,7 +151,7 @@ public class IniSerializerSession extends 
WriterSerializerSession {
                        Object value = e.getValue();
                        var iniMeta = ctx.getIniBeanPropertyMeta(pMeta);
                        var key = ne(iniMeta.getSection()) ? 
iniMeta.getSection() : pMeta.getName();
-                       var cMeta = pMeta.getClassMeta();
+                       var cMeta = (ClassMeta<?>) pMeta.getClassMeta();
                        var newPath = sectionPath.isEmpty() ? key : sectionPath 
+ "/" + key;
 
                        if (nn(value)) {
@@ -235,7 +235,7 @@ public class IniSerializerSession extends 
WriterSerializerSession {
        private void writeKeyValue(IniWriter w, String key, Object value, 
BeanPropertyMeta pMeta) throws SerializeException {
                ClassMeta<?> cMeta;
                if (pMeta != null)
-                       cMeta = pMeta.getClassMeta();
+                       cMeta = (ClassMeta<?>) pMeta.getClassMeta();
                else if (value != null)
                        cMeta = getClassMetaForObject(value);
                else
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/jcs/JcsSerializerSession.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/jcs/JcsSerializerSession.java
index 45827bcba6..8fb3e0e96e 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/jcs/JcsSerializerSession.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/jcs/JcsSerializerSession.java
@@ -280,7 +280,7 @@ public class JcsSerializerSession extends 
JsonSerializerSession {
                Predicate<Object> checkNull = x -> isKeepNullProperties() || 
nn(x);
 
                m.forEachValue(checkNull, (pMeta, key, value, thrown) -> {
-                       var cMeta = pMeta.getClassMeta();
+                       var cMeta = (ClassMeta<?>) pMeta.getClassMeta();
                        if (nn(thrown))
                                onBeanGetterException(pMeta, thrown);
                        if (canIgnoreValue(cMeta, key, value))
@@ -302,7 +302,7 @@ public class JcsSerializerSession extends 
JsonSerializerSession {
                for (var entry : entries) {
                        addComma.ifSet(() -> out.append(',').smi(i)).set();
                        out.cr(i).attr(entry.getKey()).w(':').s(i);
-                       serializeAnything(out, entry.getValue(), 
entry.pMeta.getClassMeta(), entry.getKey(), entry.pMeta);
+                       serializeAnything(out, entry.getValue(), (ClassMeta<?>) 
entry.pMeta.getClassMeta(), entry.getKey(), entry.pMeta);
                }
 
                out.cre(i - 1).w('}');
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/JsonParserSession.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/JsonParserSession.java
index 2929885d85..3cebc8f3c1 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/JsonParserSession.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/JsonParserSession.java
@@ -424,17 +424,17 @@ public class JsonParserSession extends 
ReaderParserSession {
                                        if (isCommentOrWhitespace(c)) {
                                                
skipCommentsAndSpace(r.unread());
                                        } else {
-                                               if (! 
currAttr.equals(getBeanTypePropertyName(m.getClassMeta()))) {
-                                                       var pMeta = 
m.getPropertyMeta(currAttr);
-                                                       
setCurrentProperty(pMeta);
-                                                       if (pMeta == null) {
-                                                               
onUnknownProperty(currAttr, m, parseAnything(object(), r.unread(), 
m.getBean(false), null));
-                                                               unmark();
-                                                       } else {
-                                                               unmark();
-                                                               var cm = 
pMeta.getClassMeta();
-                                                               Object value = 
parseAnything(cm, r.unread(), m.getBean(false), pMeta);
-                                                               setName(cm, 
value, currAttr);
+                                       if (! 
currAttr.equals(getBeanTypePropertyName((ClassMeta<?>) m.getClassMeta()))) {
+                                               var pMeta = 
m.getPropertyMeta(currAttr);
+                                               setCurrentProperty(pMeta);
+                                               if (pMeta == null) {
+                                                       
onUnknownProperty(currAttr, m, parseAnything(object(), r.unread(), 
m.getBean(false), null));
+                                                       unmark();
+                                               } else {
+                                                       unmark();
+                                                       var cm = (ClassMeta<?>) 
pMeta.getClassMeta();
+                                                       Object value = 
parseAnything(cm, r.unread(), m.getBean(false), pMeta);
+                                                       setName(cm, value, 
currAttr);
                                                                try {
                                                                        
pMeta.set(m, currAttr, value);
                                                                } catch 
(BeanRuntimeException e) {
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/JsonSerializerSession.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/JsonSerializerSession.java
index cdfd656a50..9e2c9e2517 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/JsonSerializerSession.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/JsonSerializerSession.java
@@ -249,7 +249,7 @@ public class JsonSerializerSession extends 
WriterSerializerSession {
                }
 
                m.forEachValue(checkNull, (pMeta, key, value, thrown) -> {
-                       var cMeta = pMeta.getClassMeta();
+                       var cMeta = (ClassMeta<?>) pMeta.getClassMeta();
                        if (nn(thrown))
                                onBeanGetterException(pMeta, thrown);
 
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/jsonschema/JsonSchemaGeneratorSession.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/jsonschema/JsonSchemaGeneratorSession.java
index 4e4befe4b5..394207feaf 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/jsonschema/JsonSchemaGeneratorSession.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/jsonschema/JsonSchemaGeneratorSession.java
@@ -450,7 +450,7 @@ public class JsonSchemaGeneratorSession extends 
MarshallingTraverseSession {
                                        BeanPropertyMeta p = i.next();
                                        if (p.canRead()) {
                                                var pProps = p.getProperties();
-                                               properties.put(p.getName(), 
getSchema(p.getClassMeta(), p.getName(), pProps, exampleAdded, 
descriptionAdded, getJsonSchemaBeanPropertyMeta(p)));
+                                               properties.put(p.getName(), 
getSchema((ClassMeta<?>) p.getClassMeta(), p.getName(), pProps, exampleAdded, 
descriptionAdded, getJsonSchemaBeanPropertyMeta(p)));
                                        }
                                }
                                out.put(PROP_properties, properties);
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/markdown/MarkdownDocParserSession.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/markdown/MarkdownDocParserSession.java
index dd1f0ae645..9966f5e519 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/markdown/MarkdownDocParserSession.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/markdown/MarkdownDocParserSession.java
@@ -302,7 +302,7 @@ public class MarkdownDocParserSession extends 
MarkdownParserSession {
                                                var pm = m.getPropertyMeta(key);
                                                if (pm != null) {
                                                        setCurrentProperty(pm);
-                                                       var val = 
parseCellValue(rawVal, pm.getClassMeta(), m.getBean(false));
+                                                       var val = 
parseCellValue(rawVal, (ClassMeta<?>) pm.getClassMeta(), m.getBean(false));
                                                        pm.set(m, key, val);
                                                        
setCurrentProperty(null);
                                                } else {
@@ -325,7 +325,7 @@ public class MarkdownDocParserSession extends 
MarkdownParserSession {
                                continue; // Skip root, unknown properties, or 
sections we ignore
 
                        setCurrentProperty(pm);
-                       var propCm = pm.getClassMeta();
+                       var propCm = (ClassMeta<?>) pm.getClassMeta();
 
                        // Find first content line to determine if it's a table 
or list
                        var contentLines = sectionLines.stream()
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/markdown/MarkdownParserSession.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/markdown/MarkdownParserSession.java
index 89ad73a8a3..2b0d8eca1c 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/markdown/MarkdownParserSession.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/markdown/MarkdownParserSession.java
@@ -352,9 +352,10 @@ public class MarkdownParserSession extends 
ReaderParserSession {
                                var pm = m.getPropertyMeta(key);
                                if (pm != null) {
                                        setCurrentProperty(pm);
-                                       var val = parseCellValue(rawVal, 
pm.getClassMeta(), m.getBean(false));
+                                       var pmcm = (ClassMeta<?>) 
pm.getClassMeta();
+                                       var val = parseCellValue(rawVal, pmcm, 
m.getBean(false));
                                        try {
-                                               setName(pm.getClassMeta(), val, 
key);
+                                               setName(pmcm, val, key);
                                        } catch (Exception e) {
                                                throw new ParseException(this, 
e, "Could not set @NameProperty on ''{0}''.", key);
                                        }
@@ -525,7 +526,7 @@ public class MarkdownParserSession extends 
ReaderParserSession {
                                var pm = m.getPropertyMeta(header);
                                if (pm != null) {
                                        setCurrentProperty(pm);
-                                       var val = parseCellValue(rawVal, 
pm.getClassMeta(), m.getBean(false));
+                                       var val = parseCellValue(rawVal, 
(ClassMeta<?>) pm.getClassMeta(), m.getBean(false));
                                        pm.set(m, header, val);
                                        setCurrentProperty(null);
                                } else {
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/msgpack/MsgPackParserSession.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/msgpack/MsgPackParserSession.java
index 8bd411b6cd..bd71e7c9d1 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/msgpack/MsgPackParserSession.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/msgpack/MsgPackParserSession.java
@@ -271,7 +271,7 @@ public class MsgPackParserSession extends 
InputStreamParserSession {
                                                        else
                                                                
onUnknownProperty(pName, m, parseAnything(string(), is, null, null));
                                                } else {
-                                                       var cm = 
bpm.getClassMeta();
+                                                       var cm = (ClassMeta<?>) 
bpm.getClassMeta();
                                                        Object value = 
parseAnything(cm, is, m.getBean(false), bpm);
                                                        setName(cm, value, 
pName);
                                                        try {
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/objecttools/ObjectRest.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/objecttools/ObjectRest.java
index 6d3a6a6743..fc4c346067 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/objecttools/ObjectRest.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/objecttools/ObjectRest.java
@@ -1026,7 +1026,7 @@ public class ObjectRest {
                        var pMeta = m.getPropertyMeta(parentKey);
                        if (pMeta == null)
                                throw new ObjectRestException(HTTP_BAD_REQUEST, 
"Unknown property ''{0}'' encountered while trying to parse into class 
''{1}''", parentKey, m.getClassMeta());
-                       ct2 = pMeta.getClassMeta();
+                       ct2 = (ClassMeta) pMeta.getClassMeta();
                }
 
                if (childUrl == null)
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parquet/ParquetParserSession.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parquet/ParquetParserSession.java
index 122f55560c..c93ef8c255 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parquet/ParquetParserSession.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parquet/ParquetParserSession.java
@@ -966,7 +966,7 @@ public class ParquetParserSession extends 
InputStreamParserSession {
                        var suffix = ".list.element.";
                        var suffixStart = listProp.length() + suffix.length();
                        var pMeta = rowRelPath.length() > suffixStart ? 
bm.getPropertyMeta(listProp) : null;
-                       var propClassMeta = pMeta != null ? 
pMeta.getClassMeta() : null;
+                       var propClassMeta = pMeta != null ? (ClassMeta<?>) 
pMeta.getClassMeta() : null;
                        var elemType = propClassMeta != null && 
(propClassMeta.isCollection() || propClassMeta.isArray()) ? 
propClassMeta.getElementType() : null;
                        if (elemType != null && elemType.isBean()) {
                                var elementProp = 
rowRelPath.substring(suffixStart);
@@ -1087,7 +1087,7 @@ public class ParquetParserSession extends 
InputStreamParserSession {
                for (var pMeta : bm.getProperties().values()) {
                        var name = pMeta.getName();
                        var val = row.get(name);
-                       var propType = pMeta.getClassMeta();
+                       var propType = (ClassMeta<?>) pMeta.getClassMeta();
                        if (val == null)
                                continue;
                        if (propType.isOptional() && val instanceof Map<?,?> m) 
{
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parquet/ParquetSchemaBuilder.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parquet/ParquetSchemaBuilder.java
index e78da938e6..b56fd56535 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parquet/ParquetSchemaBuilder.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parquet/ParquetSchemaBuilder.java
@@ -212,7 +212,7 @@ public final class ParquetSchemaBuilder {
                                Object childSample = null;
                                if (sampleBean != null && sampleBean instanceof 
Map<?, ?> m)
                                        childSample = m.get(p.getName());
-                               var propCm = p.getClassMeta();
+                               ClassMeta<?> propCm = (ClassMeta<?>) 
p.getClassMeta();
                                // When property type is Object, infer from 
sample so Map/Collection get proper schema (2.2)
                                if ((propCm == null || propCm.isObject()) && 
childSample != null)
                                        propCm = 
marshallingContext.getClassMeta(childSample.getClass());
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/ParserSession.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/ParserSession.java
index bd5f8a1668..4f6c49bef7 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/ParserSession.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/ParserSession.java
@@ -1215,12 +1215,13 @@ public class ParserSession extends MarshallingSession {
         * @param <T> The class type of the bean map that doesn't have the 
expected property.
         */
        protected final <T> void onUnknownProperty(String propertyName, 
BeanMap<T> beanMap, Object value) throws ParseException {
-               if 
(propertyName.equals(getBeanTypePropertyName(beanMap.getClassMeta())))
+               var bmcm = (ClassMeta<T>) beanMap.getClassMeta();
+               if (propertyName.equals(getBeanTypePropertyName(bmcm)))
                        return;
                if (! isIgnoreUnknownBeanProperties() && (nn(value) || ! 
isIgnoreUnknownNullBeanProperties()))
-                       throw new ParseException(this, "Unknown property 
''{0}'' encountered while trying to parse into class ''{1}''", propertyName, 
beanMap.getClassMeta());
+                       throw new ParseException(this, "Unknown property 
''{0}'' encountered while trying to parse into class ''{1}''", propertyName, 
bmcm);
                if (nn(listener))
-                       listener.onUnknownBeanProperty(this, propertyName, 
beanMap.getClassMeta().inner(), beanMap.getBean());
+                       listener.onUnknownBeanProperty(this, propertyName, 
bmcm.inner(), beanMap.getBean());
        }
 
        @Override /* Overridden from MarshallingSession */
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/proto/ProtoParserSession.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/proto/ProtoParserSession.java
index 7383e6dc4b..3af2dc4521 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/proto/ProtoParserSession.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/proto/ProtoParserSession.java
@@ -266,7 +266,7 @@ public class ProtoParserSession extends ReaderParserSession 
{
        }
 
        private void populateBeanMap(BeanMap<?> bm, Map<String, Object> map) 
throws ParseException, ExecutableException {
-               var typePropName = getBeanTypePropertyName(bm.getClassMeta());
+               var typePropName = getBeanTypePropertyName((ClassMeta<?>) 
bm.getClassMeta());
                for (Entry<String, Object> e : map.entrySet()) {
                        var key = e.getKey();
                        if (key.equals(typePropName))
@@ -277,7 +277,7 @@ public class ProtoParserSession extends ReaderParserSession 
{
                                continue;
                        if (pMeta == null)
                                throw new ParseException(this, "Unknown 
property ''{0}''", key);
-                       var targetType = pMeta.getClassMeta();
+                       var targetType = (ClassMeta<?>) pMeta.getClassMeta();
                        var converted = convertValue(val, targetType);
                        bm.put(key, converted);
                }
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/proto/ProtoSerializerSession.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/proto/ProtoSerializerSession.java
index ab869d97ff..2372544fe7 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/proto/ProtoSerializerSession.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/proto/ProtoSerializerSession.java
@@ -246,13 +246,13 @@ public class ProtoSerializerSession extends 
WriterSerializerSession {
                                onBeanGetterException(pMeta, thrown);
                        if (value == null)
                                return;
-                       if (canIgnoreValue(pMeta.getClassMeta(), key, value))
+                       var cMeta = (ClassMeta<?>) pMeta.getClassMeta();
+                       if (canIgnoreValue(cMeta, key, value))
                                return;
                        var protoPMeta = ctx.getProtoBeanPropertyMeta(pMeta);
                        if (nn(protoPMeta) && 
!protoPMeta.getComment().isEmpty())
                                out.comment(protoPMeta.getComment());
                        out.cr(indent);
-                       var cMeta = pMeta.getClassMeta();
                        var aType = getClassMetaForObject(value, cMeta);
                        if (aType.isBean() || aType.isMap()) {
                                out.messageStart(key, ctx.useColonForMessages);
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/toml/TomlParserSession.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/toml/TomlParserSession.java
index f5cd29bc9c..07db20e614 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/toml/TomlParserSession.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/toml/TomlParserSession.java
@@ -378,7 +378,7 @@ public class TomlParserSession extends ReaderParserSession {
                                continue;
                        if (pMeta == null)
                                throw new ParseException(this, "Unknown 
property ''{0}''", key);
-                       ClassMeta<?> targetType = pMeta.getClassMeta();
+                       ClassMeta<?> targetType = (ClassMeta<?>) 
pMeta.getClassMeta();
                        Object converted = convertValue(val, targetType);
                        bm.put(key, converted);
                }
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/toml/TomlSerializerSession.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/toml/TomlSerializerSession.java
index f5d9ab690e..aa9ccba5bd 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/toml/TomlSerializerSession.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/toml/TomlSerializerSession.java
@@ -156,9 +156,9 @@ public class TomlSerializerSession extends 
WriterSerializerSession {
                m.forEachValue(checkNull, (pMeta, key, value, thrown) -> {
                        if (nn(thrown))
                                onBeanGetterException(pMeta, thrown);
-                       if (canIgnoreValue(pMeta.getClassMeta(), key, value))
+                       ClassMeta<?> cMeta = (ClassMeta<?>) 
pMeta.getClassMeta();
+                       if (canIgnoreValue(cMeta, key, value))
                                return;
-                       ClassMeta<?> cMeta = pMeta.getClassMeta();
                        ClassMeta<?> aType = value == null ? cMeta : 
getClassMetaForObject(value, cMeta);
                        if (isSimpleOrInlineTable(aType, value, pMeta)) {
                                simple.add(new AbstractMap.SimpleEntry<>(pMeta, 
value));
@@ -185,7 +185,7 @@ public class TomlSerializerSession extends 
WriterSerializerSession {
                        String key = e.getKey().getName();
                        Object value = e.getValue();
                        BeanPropertyMeta pMeta = e.getKey();
-                       ClassMeta<?> cMeta = pMeta.getClassMeta();
+                       ClassMeta<?> cMeta = (ClassMeta<?>) 
pMeta.getClassMeta();
                        String newPath = tablePath.isEmpty() ? key : tablePath 
+ "." + key;
 
                        if (nn(value)) {
@@ -220,7 +220,7 @@ public class TomlSerializerSession extends 
WriterSerializerSession {
        private void writeKeyValue(TomlWriter w, String key, Object value, 
BeanPropertyMeta pMeta) throws SerializeException {
                ClassMeta<?> cMeta;
                if (pMeta != null)
-                       cMeta = pMeta.getClassMeta();
+                       cMeta = (ClassMeta<?>) pMeta.getClassMeta();
                else if (value != null)
                        cMeta = getClassMetaForObject(value);
                else
@@ -292,7 +292,7 @@ public class TomlSerializerSession extends 
WriterSerializerSession {
                                        first[0] = false;
                                        writeKey(w, k);
                                        w.w(" = ");
-                               writeValue(w, v, pm.getClassMeta(), pm);
+                               writeValue(w, v, (ClassMeta<?>) 
pm.getClassMeta(), pm);
                                });
                                w.inlineTableEnd();
                        } else {
@@ -371,7 +371,7 @@ public class TomlSerializerSession extends 
WriterSerializerSession {
                int count = 0;
                for (BeanPropertyMeta p : 
bm.getMeta().getProperties().values()) {
                        if (!p.isReadOnly()) {
-                               ClassMeta<?> cm = p.getClassMeta();
+                               ClassMeta<?> cm = (ClassMeta<?>) 
p.getClassMeta();
                                if (cm.isBean() || cm.isMap() || 
(cm.isCollectionOrArray() && cm.getElementType().isBean()))
                                        return false;
                                count++;
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/uon/UonParserSession.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/uon/UonParserSession.java
index 59fc460fe3..eb59f5d715 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/uon/UonParserSession.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/uon/UonParserSession.java
@@ -549,14 +549,14 @@ public class UonParserSession extends ReaderParserSession 
implements HttpPartPar
                                                }
                                        } else if (state == S3) {
                                                if (c == -1 || c == ',' || c == 
')' || c == AMP) {
-                                                       if (! 
currAttr.equals(getBeanTypePropertyName(m.getClassMeta()))) {
+                                                       if (! 
currAttr.equals(getBeanTypePropertyName((ClassMeta<?>) m.getClassMeta()))) {
                                                                var pMeta = 
m.getPropertyMeta(currAttr);
                                                                if (pMeta == 
null) {
                                                                        
onUnknownProperty(currAttr, m, null);
                                                                        
unmark();
                                                                } else {
                                                                        
unmark();
-                                                                       var 
value = convertToType("", pMeta.getClassMeta());
+                                                                       var 
value = convertToType("", (ClassMeta<?>) pMeta.getClassMeta());
                                                                        try {
                                                                                
pMeta.set(m, currAttr, value);
                                                                        } catch 
(BeanRuntimeException e) {
@@ -569,7 +569,7 @@ public class UonParserSession extends ReaderParserSession 
implements HttpPartPar
                                                                return m;
                                                        state = S1;
                                                } else {
-                                                       if (! 
currAttr.equals(getBeanTypePropertyName(m.getClassMeta()))) {
+                                                       if (! 
currAttr.equals(getBeanTypePropertyName((ClassMeta<?>) m.getClassMeta()))) {
                                                                var pMeta = 
m.getPropertyMeta(currAttr);
                                                                if (pMeta == 
null) {
                                                                        
onUnknownProperty(currAttr, m, parseAnything(object(), r.unread(), 
m.getBean(false), false, null));
@@ -577,7 +577,7 @@ public class UonParserSession extends ReaderParserSession 
implements HttpPartPar
                                                                } else {
                                                                        
unmark();
                                                                        
setCurrentProperty(pMeta);
-                                                                       var cm 
= pMeta.getClassMeta();
+                                                                       var cm 
= (ClassMeta<?>) pMeta.getClassMeta();
                                                                        var 
value = parseAnything(cm, r.unread(), m.getBean(false), false, pMeta);
                                                                        
setName(cm, value, currAttr);
                                                                        try {
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/uon/UonSerializerSession.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/uon/UonSerializerSession.java
index c44f4863ba..7d66567bd2 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/uon/UonSerializerSession.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/uon/UonSerializerSession.java
@@ -297,7 +297,7 @@ public class UonSerializerSession extends 
WriterSerializerSession implements Htt
 
                var checkNull = (Predicate<Object>)(x -> isKeepNullProperties() 
|| nn(x));
                m.forEachValue(checkNull, (pMeta, key, value, thrown) -> {
-                       var cMeta = pMeta.getClassMeta();
+                       var cMeta = (ClassMeta<?>) pMeta.getClassMeta();
 
                        if (nn(thrown))
                                onBeanGetterException(pMeta, thrown);
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/urlencoding/UrlEncodingParserSession.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/urlencoding/UrlEncodingParserSession.java
index a1a0355293..ea5407aa50 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/urlencoding/UrlEncodingParserSession.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/urlencoding/UrlEncodingParserSession.java
@@ -236,8 +236,8 @@ public class UrlEncodingParserSession extends 
UonParserSession {
         * @return <jk>true</jk> if the specified bean property should be 
expanded as multiple key-value pairs.
         */
        public final boolean shouldUseExpandedParams(BeanPropertyMeta pMeta) {
-               var cm = pMeta.getClassMeta().getSerializedClassMeta(this);
-               return cm.isCollectionOrArray() && (isExpandedParams() || 
getUrlEncodingClassMeta(pMeta.getBeanMeta().getClassMeta()).isExpandedParams());
+               var cm = ((ClassMeta<?>) 
pMeta.getClassMeta()).getSerializedClassMeta(this);
+               return cm.isCollectionOrArray() && (isExpandedParams() || 
getUrlEncodingClassMeta((ClassMeta<?>) 
pMeta.getBeanMeta().getClassMeta()).isExpandedParams());
        }
 
        @SuppressWarnings({
@@ -373,7 +373,7 @@ public class UrlEncodingParserSession extends 
UonParserSession {
                                                }
                                        } else if (state == S3) {  // NOSONAR - 
State check necessary for state machine
                                                if (c == -1 || c == '\u0001') {
-                                                       if (! 
currAttr.equals(getBeanTypePropertyName(m.getClassMeta()))) {
+                                                       if (! 
currAttr.equals(getBeanTypePropertyName((ClassMeta<?>) m.getClassMeta()))) {
                                                                var pMeta = 
m.getPropertyMeta(currAttr);
                                                                if (pMeta == 
null) {
                                                                        
onUnknownProperty(currAttr, m, null);
@@ -383,7 +383,7 @@ public class UrlEncodingParserSession extends 
UonParserSession {
                                                                        
setCurrentProperty(pMeta);
                                                                        // In 
cases of "&foo=", create an empty instance of the value if createable.
                                                                        // 
Otherwise, leave it null.
-                                                                       var cm 
= pMeta.getClassMeta();
+                                                                       var cm 
= (ClassMeta<?>) pMeta.getClassMeta();
                                                                        if 
(cm.canCreateNewInstance()) {
                                                                                
try {
                                                                                
        pMeta.set(m, currAttr, cm.newInstance());
@@ -399,7 +399,7 @@ public class UrlEncodingParserSession extends 
UonParserSession {
                                                                return m;
                                                        state = S1;
                                                } else {
-                                                       if (! 
currAttr.equals(getBeanTypePropertyName(m.getClassMeta()))) {
+                                                       if (! 
currAttr.equals(getBeanTypePropertyName((ClassMeta<?>) m.getClassMeta()))) {
                                                                var pMeta = 
m.getPropertyMeta(currAttr);
                                                                if (pMeta == 
null) {
                                                                        
onUnknownProperty(currAttr, m, parseAnything(object(), r.unread(), 
m.getBean(false), true, null));
@@ -408,7 +408,7 @@ public class UrlEncodingParserSession extends 
UonParserSession {
                                                                        
unmark();
                                                                        
setCurrentProperty(pMeta);
                                                                        if 
(shouldUseExpandedParams(pMeta)) {
-                                                                               
var et = pMeta.getClassMeta().getElementType();
+                                                                               
var et = ((ClassMeta<?>) pMeta.getClassMeta()).getElementType();
                                                                                
var value = parseAnything(et, r.unread(), m.getBean(false), true, pMeta);
                                                                                
setName(et, value, currAttr);
                                                                                
try {
@@ -418,7 +418,7 @@ public class UrlEncodingParserSession extends 
UonParserSession {
                                                                                
        throw e;
                                                                                
}
                                                                        } else {
-                                                                               
var cm = pMeta.getClassMeta();
+                                                                               
var cm = (ClassMeta<?>) pMeta.getClassMeta();
                                                                                
var value = parseAnything(cm, r.unread(), m.getBean(false), true, pMeta);
                                                                                
setName(cm, value, currAttr);
                                                                                
try {
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializerSession.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializerSession.java
index 84dbaa8e62..1babb38907 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializerSession.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializerSession.java
@@ -327,7 +327,7 @@ public class UrlEncodingSerializerSession extends 
UonSerializerSession {
 
                Predicate<Object> checkNull = x -> isKeepNullProperties() || 
nn(x);
                m.forEachValue(checkNull, (pMeta, key, value, thrown) -> {
-                       var cMeta = pMeta.getClassMeta();
+                       var cMeta = (ClassMeta<?>) pMeta.getClassMeta();
                        var sMeta = cMeta.getSerializedClassMeta(this);
 
                        if (nn(thrown))
@@ -430,8 +430,8 @@ public class UrlEncodingSerializerSession extends 
UonSerializerSession {
         * Returns <jk>true</jk> if the specified bean property should be 
expanded as multiple key-value pairs.
         */
        private boolean shouldUseExpandedParams(BeanPropertyMeta pMeta) {
-               var cm = pMeta.getClassMeta().getSerializedClassMeta(this);
-               return cm.isCollectionOrArray() && (isExpandedParams() || 
getUrlEncodingClassMeta(pMeta.getBeanMeta().getClassMeta()).isExpandedParams());
+               var cm = ((ClassMeta<?>) 
pMeta.getClassMeta()).getSerializedClassMeta(this);
+               return cm.isCollectionOrArray() && (isExpandedParams() || 
getUrlEncodingClassMeta((ClassMeta<?>) 
pMeta.getBeanMeta().getClassMeta()).isExpandedParams());
        }
 
        /*
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xml/XmlBeanMeta.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xml/XmlBeanMeta.java
index dbec15972e..fdd1eaa7f0 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xml/XmlBeanMeta.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xml/XmlBeanMeta.java
@@ -50,11 +50,12 @@ public class XmlBeanMeta extends ExtendedBeanMeta {
                        "java:S3776" // Cognitive complexity acceptable for XML 
bean metadata building
                })
                XmlBeanMetaBuilder(BeanMeta<?> beanMeta, XmlMetaProvider mp) {
-                       var c = beanMeta.getClassMeta().inner();
-                       var ci = beanMeta.getClassMeta();
+                       var bmcm = (ClassMeta<?>) beanMeta.getClassMeta();
+                       var c = bmcm.inner();
+                       var ci = bmcm;
                        var defaultFormat = Value.<XmlFormat>empty();
 
-                       
beanMeta.getClassMeta().getMarshallingContext().getAnnotationProvider().find(Xml.class,
 ci).stream().map(AnnotationInfo::inner).forEach(x -> {
+                       
bmcm.getMarshallingContext().getAnnotationProvider().find(Xml.class, 
ci).stream().map(AnnotationInfo::inner).forEach(x -> {
                                var xf = x.format();
                                if (xf == ATTRS)
                                        defaultFormat.set(XmlFormat.ATTR);
@@ -69,7 +70,7 @@ public class XmlBeanMeta extends ExtendedBeanMeta {
 
                        beanMeta.getProperties().values().forEach(p -> {
                                var xf = 
mp.getXmlBeanPropertyMeta(p).getXmlFormat();
-                               var pcm = p.getClassMeta();
+                               var pcm = (ClassMeta<?>) p.getClassMeta();
                                if (xf == ATTR) {
                                        attrs.put(p.getName(), p);
                                } else if (xf == ELEMENT) {
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xml/XmlBeanPropertyMeta.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xml/XmlBeanPropertyMeta.java
index 06b9dc2ee1..00eb7bb0c4 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xml/XmlBeanPropertyMeta.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xml/XmlBeanPropertyMeta.java
@@ -55,10 +55,10 @@ public class XmlBeanPropertyMeta extends 
ExtendedBeanPropertyMeta {
                super(bpm);
                this.xmlMetaProvider = mp;
 
-               bpm.getAnnotations(Xml.class).forEach(x -> 
findXmlInfo(x.inner(), 
bpm.getClassMeta().getMarshallingContext().getAnnotationProvider()));
+               bpm.getAnnotations(Xml.class).forEach(x -> 
findXmlInfo(x.inner(), ((ClassMeta<?>) 
bpm.getClassMeta()).getMarshallingContext().getAnnotationProvider()));
 
                if (namespace == null)
-                       namespace = 
mp.getXmlClassMeta(bpm.getBeanMeta().getClassMeta()).getNamespace();
+                       namespace = mp.getXmlClassMeta((ClassMeta<?>) 
bpm.getBeanMeta().getClassMeta()).getNamespace();
        }
 
        private XmlBeanPropertyMeta() {
@@ -110,17 +110,17 @@ public class XmlBeanPropertyMeta extends 
ExtendedBeanPropertyMeta {
                if (xml == null)
                        return;
                var bpm = getBeanPropertyMeta();
-               var cmProperty = bpm.getClassMeta();
-               var cmBean = bpm.getBeanMeta().getClassMeta();
+               var cmProperty = (ClassMeta<?>) bpm.getClassMeta();
+               var cmBean = (ClassMeta<?>) bpm.getBeanMeta().getClassMeta();
                var name = bpm.getName();
 
-               var ap = 
bpm.getClassMeta().getMarshallingContext().getAnnotationProvider();
+               var ap = 
cmProperty.getMarshallingContext().getAnnotationProvider();
                var xmls = new MultiList<>(
-                       rstream(ap.find(Xml.class, 
bpm.getBeanMeta().getClassMeta())).map(AnnotationInfo::inner).toList(),
+                       rstream(ap.find(Xml.class, 
cmBean)).map(AnnotationInfo::inner).toList(),
                        
reverse(bpm.getAnnotations(Xml.class).map(AnnotationInfo::inner).toList())
                );
                var schemas = new MultiList<>(
-                       rstream(ap.find(XmlSchema.class, 
bpm.getBeanMeta().getClassMeta())).map(AnnotationInfo::inner).toList(),
+                       rstream(ap.find(XmlSchema.class, 
cmBean)).map(AnnotationInfo::inner).toList(),
                        
reverse(bpm.getAnnotations(XmlSchema.class).map(AnnotationInfo::inner).toList())
                );
                namespace = XmlUtils.findNamespace(xmls, schemas);
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xml/XmlParserSession.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xml/XmlParserSession.java
index 7b8d2bd23a..52fce04925 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xml/XmlParserSession.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xml/XmlParserSession.java
@@ -461,7 +461,7 @@ public class XmlParserSession extends ReaderParserSession {
                var cp = xmlMeta.getContentProperty();
                var cpf = xmlMeta.getContentFormat();
                var trim = cp == null || ! cpf.isOneOf(MIXED_PWS, TEXT_PWS);
-               var cpcm = (cp == null ? object() : cp.getClassMeta());
+               ClassMeta<?> cpcm = (cp == null ? object() : (ClassMeta<?>) 
cp.getClassMeta());
                StringBuilder sb = null;
                var breg = cp == null ? null : cp.getBeanRegistry();
                List<Object> l = null;
@@ -537,7 +537,7 @@ public class XmlParserSession extends ReaderParserSession {
                                                setCurrentProperty(pMeta);
                                                var xf = 
getXmlBeanPropertyMeta(pMeta).getXmlFormat();
                                                if (xf == COLLAPSED) {
-                                                       var et = 
pMeta.getClassMeta().getElementType();
+                                                       var et = 
((ClassMeta<?>) pMeta.getClassMeta()).getElementType();
                                                        var value = 
parseAnything(et, currAttr, r, m.getBean(false), false, pMeta);
                                                        setName(et, value, 
currAttr);
                                                        pMeta.add(m, currAttr, 
value);
@@ -545,7 +545,7 @@ public class XmlParserSession extends ReaderParserSession {
                                                        pMeta.set(m, currAttr, 
getAttributeValue(r, 0));
                                                        r.nextTag();
                                                } else {
-                                                       var cm = 
pMeta.getClassMeta();
+                                                       var cm = (ClassMeta<?>) 
pMeta.getClassMeta();
                                                        var value = 
parseAnything(cm, currAttr, r, m.getBean(false), false, pMeta);
                                                        setName(cm, value, 
currAttr);
                                                        pMeta.set(m, currAttr, 
value);
@@ -923,7 +923,7 @@ public class XmlParserSession extends ReaderParserSession {
                                var fieldName = r.getLocalName();
                                var m = nn(builder) ? 
toBeanMap(builder.create(this, eType)) : newBeanMap(outer, sType.inner());
                                var bpm = 
getXmlBeanMeta(m.getMeta()).getPropertyMeta(fieldName);
-                               var cm = m.getMeta().getClassMeta();
+                               var cm = (ClassMeta<?>) 
m.getMeta().getClassMeta();
                                Object value = parseAnything(cm, currAttr, r, 
m.getBean(false), false, null);
                                setName(cm, value, currAttr);
                                bpm.set(m, currAttr, value);
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/yaml/YamlParserSession.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/yaml/YamlParserSession.java
index 948dba03c2..c42fa76175 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/yaml/YamlParserSession.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/yaml/YamlParserSession.java
@@ -523,7 +523,7 @@ public class YamlParserSession extends ReaderParserSession {
                if (pm == null) {
                        onUnknownProperty(currAttr, m, parseAnything(object(), 
r, m.getBean(false), null));
                } else {
-                       var cm = pm.getClassMeta();
+                       var cm = (ClassMeta<?>) pm.getClassMeta();
                        Object value = parseAnything(cm, r, m.getBean(false), 
pm);
                        setName(cm, value, currAttr);
                        try {
@@ -928,7 +928,7 @@ public class YamlParserSession extends ReaderParserSession {
                                } else if (state == S4) {
                                        if (isWhitespace(c))
                                                continue;
-                                       if (! 
currAttr.equals(getBeanTypePropertyName(m.getClassMeta()))) {
+                                       if (! 
currAttr.equals(getBeanTypePropertyName((ClassMeta<?>) m.getClassMeta()))) {
                                                var pm = 
m.getPropertyMeta(currAttr);
                                                setCurrentProperty(pm);
                                                if (pm == null) {
@@ -936,7 +936,7 @@ public class YamlParserSession extends ReaderParserSession {
                                                        unmark();
                                                } else {
                                                        unmark();
-                                                       var cm = 
pm.getClassMeta();
+                                                       var cm = (ClassMeta<?>) 
pm.getClassMeta();
                                                        Object value = 
parseAnything(cm, r.unread(), m.getBean(false), pm);
                                                        setName(cm, value, 
currAttr);
                                                        try {
@@ -1017,7 +1017,7 @@ public class YamlParserSession extends 
ReaderParserSession {
                                if (c != ':')
                                        throw new ParseException(this, 
"Expected ':' after attribute name in YAML block mapping, found ''{0}''", 
(char)c);
 
-                               if (! 
currAttr.equals(getBeanTypePropertyName(m.getClassMeta()))) {
+                               if (! 
currAttr.equals(getBeanTypePropertyName((ClassMeta<?>) m.getClassMeta()))) {
                                        var pm = m.getPropertyMeta(currAttr);
                                        setCurrentProperty(pm);
                                        if (pm == null) {
@@ -1029,7 +1029,7 @@ public class YamlParserSession extends 
ReaderParserSession {
                                                unmark();
                                        } else {
                                                unmark();
-                                               var cm = pm.getClassMeta();
+                                               var cm = (ClassMeta<?>) 
pm.getClassMeta();
                                                c = r.peek();
                                                if (c == ' ')
                                                        r.read();
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/yaml/YamlSerializerSession.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/yaml/YamlSerializerSession.java
index 0382ec432b..0318f94764 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/yaml/YamlSerializerSession.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/yaml/YamlSerializerSession.java
@@ -340,7 +340,7 @@ public class YamlSerializerSession extends 
WriterSerializerSession {
                }
 
                m.forEachValue(checkNull, (pMeta, key, value, thrown) -> {
-                       var cMeta = pMeta.getClassMeta();
+                       var cMeta = (ClassMeta<?>) pMeta.getClassMeta();
                        if (nn(thrown))
                                onBeanGetterException(pMeta, thrown);
 
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/beans/BeanDescription.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/beans/BeanDescription.java
index 5945473ea0..390d8f7be7 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/beans/BeanDescription.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/beans/BeanDescription.java
@@ -96,6 +96,6 @@ public class BeanDescription {
                properties = new 
BeanPropertyDescription[bm.getProperties().size()];
                int i = 0;
                for (var pm : bm.getProperties().values())
-                       properties[i++] = new 
BeanPropertyDescription(pm.getName(), pm.getClassMeta());
+                       properties[i++] = new 
BeanPropertyDescription(pm.getName(), (ClassMeta<?>) pm.getClassMeta());
        }
 }
\ No newline at end of file
diff --git a/juneau-utest/src/test/java/org/apache/juneau/BeanMap_Test.java 
b/juneau-utest/src/test/java/org/apache/juneau/BeanMap_Test.java
index 021e82bfff..83bb6e7193 100755
--- a/juneau-utest/src/test/java/org/apache/juneau/BeanMap_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/BeanMap_Test.java
@@ -439,7 +439,7 @@ class BeanMap_Test extends TestBase {
 
                var p = Json5Parser.create().beanDictionary(D2.class).build();
                m.put("lb1", JsonList.ofText("[{_type:'D2',s:'foobar'}]", p));
-               assertBean(t, 
"lb1{class{simpleName}},lb1{0{class{simpleName}}},lb1{0{s}}", 
"{{JsonList}},{{{D2}}},{{foobar}}");
+               assertBean(t, 
"lb1{class{simpleName}},lb1{0{class{simpleName}}},lb1{0{s}}", 
"{{ArrayList}},{{{D2}}},{{foobar}}");
 
                m.put("lb2", JsonList.ofText("[{_type:'D2',s:'foobar'}]", p));
                assertBean(t, 
"lb2{class{simpleName}},lb2{0{class{simpleName}}},lb2{0{s}}", 
"{{ArrayList}},{{{D2}}},{{foobar}}");
@@ -482,7 +482,7 @@ class BeanMap_Test extends TestBase {
 
                var p = 
Json5Parser.create().beanDictionary(D2c.class).applyAnnotations(D1cConfig.class).build();
                m.put("lb1", JsonList.ofText("[{_type:'D2',s:'foobar'}]", p));
-               assertBean(t, 
"lb1{class{simpleName}},lb1{0{class{simpleName}}},lb1{0{s}}", 
"{{JsonList}},{{{D2c}}},{{foobar}}");
+               assertBean(t, 
"lb1{class{simpleName}},lb1{0{class{simpleName}}},lb1{0{s}}", 
"{{ArrayList}},{{{D2c}}},{{foobar}}");
 
                m.put("lb2", JsonList.ofText("[{_type:'D2',s:'foobar'}]", p));
                assertBean(t, 
"lb2{class{simpleName}},lb2{0{class{simpleName}}},lb2{0{s}}", 
"{{ArrayList}},{{{D2c}}},{{foobar}}");
@@ -571,7 +571,7 @@ class BeanMap_Test extends TestBase {
 
                assertMapped(m, (map,prop) -> 
map.get(prop).getClass().getSimpleName(),
                        "l2,l3,l4,m2,m3,m4",
-                       
"LinkedList,JsonList,LinkedList,LinkedList,JsonList,LinkedList");
+                       
"LinkedList,ArrayList,LinkedList,LinkedList,ArrayList,LinkedList");
 
                assertMapped(m, (map,prop) -> 
((List)map.get(prop)).get(0).getClass().getSimpleName(),
                        "l2,l3,l4,m2,m3,m4",
diff --git a/todo/TODO-5-bean-runtime-types-to-commons.md 
b/todo/TODO-5-bean-runtime-types-to-commons.md
index 5cd96bef5e..1be86c3f7c 100644
--- a/todo/TODO-5-bean-runtime-types-to-commons.md
+++ b/todo/TODO-5-bean-runtime-types-to-commons.md
@@ -110,6 +110,18 @@ Known limitations of the commons-side path (acceptable for 
Step 6, scoped for la
   - **Sub-item 10 (`JsonList` / `JsonMap` → JDK collections)** — partial. The 
`propertyCache` allocations inside 
`BeanPropertyMeta.add(BeanMap,String,Object)` and 
`add(BeanMap,String,String,Object)` now use `new ArrayList<>()` / `new 
LinkedHashMap<>()` (test-invisible — they're internal caches for read-only 
beans). The `c = new JsonList(session)` / `map = new JsonMap(session)` fallback 
constructions in `add(...)` likewise flipped to `new ArrayList<>()` / `new 
LinkedHashMap<>()`. **Deferr [...]
   - **Sub-item 8 (`BeanMap.load(...)` → `BeanMapLoader`)** — created 
`juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanMapLoader.java`
 with `static <T> BeanMap<T> load(BeanMap<T> m, String input) throws 
ParseException` and `static <T> BeanMap<T> load(BeanMap<T> m, Reader r, 
ReaderParser p) throws ParseException, IOException`. Removed 
`BeanMap.load(Reader, ReaderParser)` and `BeanMap.load(String)` from 
`BeanMap.java`. Updated 2 call sites in `MarshallingContext.java` (`bs.n [...]
 
+  **Phase C status (uncommitted, working tree) — IN PROGRESS. Tasks 1, 2, 4 
LANDED, build + full test green. Tasks 3, 5 NOT STARTED.**
+
+  Phase C-tasks-1-2-and-4 landed:
+  - **Task 1 (public getter widening) — COMPLETE.** 
`BeanPropertyMeta.getClassMeta()` now returns `BeanTypeInfo<?>` (was 
`ClassMeta<?>`). `BeanMeta.getClassMeta()` now returns `BeanTypeInfo<T>` (was 
`ClassMeta<T>`). `BeanMeta.getBeanRegistry()` and 
`BeanMeta.getPropertyBeanRegistry(BeanPropertyMeta)` now return 
`BeanRegistryLookup` (was `BeanRegistry`). `BeanMap.getClassMeta()` now returns 
`BeanTypeInfo<T>` (was `ClassMeta<T>`). The cascade across ~30 marshalling-side 
files needed explic [...]
+  - **Task 2 (`validate(...)` body lift-out) — COMPLETE (signature seam).** 
Introduced new SPI `BeanTypeResolver` in `org.apache.juneau.commons.bean` 
(3-method interface: `resolveType(AnnotationInfo<BeanProp>, ClassInfo, 
TypeVariables)`, `objectType()`, `getAnnotationProvider()`). 
`MarshallingContext` now `implements BeanTypeResolver` and exposes two new 
public bridge methods (`resolveType` delegating to the existing protected 
`resolveClassMeta`, and `objectType` returning `cmObject`). ` [...]
+  - **Task 4 (`new JsonList(valueList)` → `new ArrayList<>(valueList)`) — 
COMPLETE.** `BeanPropertyMeta.setPropertyValue`'s abstract-Collection branch 
(the path that builds a typed collection by copying then converting elements) 
now constructs `new ArrayList<>(valueList)` instead of `new 
JsonList(valueList)`. Three `BeanMap_Test` assertions (`a05_arrayProperties`, 
`a06_arrayProperties_usingConfig`, `a09_beanPropertyAnnotation`) updated to 
expect `ArrayList` for the corresponding `lb1`/`l [...]
+
+  Phase C-tasks-3-and-5 NOT started:
+  - **Task 3 — `BeanMeta` constructor body lift-out** — the 
`BeanMeta(BeanTypeInfo<T>, BeanFilter, String[], ClassInfo)` constructor still 
contains marshalling-layer-aware logic (cast back to `ClassMeta<T>` to read 
`getMarshallingContext()` / `getBeanConfigContext()`, builds swap-aware 
transforms, registers per-property `BeanRegistry`). Moving that body to a 
marshalling-side helper (`MarshalledBeanMetaInitializer`) so the commons-side 
constructor body is commons-clean is still pending.
+  - **Task 4 (deferred CharSequence-parsing sites)** — two 
`CharSequence`-handling sites inside `setPropertyValue` are still in place: 
`value1 = JsonMap.ofJson(value21).session(session)` (line 1147, Map branch) and 
`value1 = new JsonList(value2).setBeanSession(session)` (line 1205, Collection 
branch). These invoke the marshalling-side JSON parser and should move to a 
marshalling-side conversion helper before `BeanPropertyMeta` physically moves 
(or be lifted into a pre-`set(...)` conversi [...]
+  - **Task 5 — Physical `git mv` + reference sweep** — the 8 target files 
(`BeanMap`, `BeanMapEntry`, `BeanMeta`, `BeanMetaFiltered`, `BeanPropertyMeta`, 
`BeanPropertyValue`, `BeanPropertyConsumer`, `BeanProxyInvocationHandler`) are 
still in `juneau-core/juneau-marshall/src/main/java/org/apache/juneau/`. Before 
the move can succeed cleanly, the marshalling-side imports in the 8 files still 
need cleanup: `BeanMap` imports `annotation.*`, `internal.*`, `swap.*`; 
`BeanMapEntry` imports `ann [...]
+
   **Phase B status (uncommitted, working tree) — COMPLETE, build + full test 
green (49,912 tests pass).**
 
   Field retypes landed (all use the "type the field against the commons.bean 
SPI seam; keep the public getter returning the marshalling-side type via a 
cast" pattern, so external callers don't need to change):
@@ -124,11 +136,11 @@ Known limitations of the commons-side path (acceptable 
for Step 6, scoped for la
 
   Remaining sub-items (deferred to Phase C):
 
-  - **Phase C — Public API widen.** `BeanPropertyMeta.getClassMeta()` → 
`BeanTypeInfo<?>`, `BeanMeta.getClassMeta()` → `BeanTypeInfo<T>` (or remove 
from the bean-modeling layer entirely), 
`BeanMeta.getBeanRegistry()`/`getPropertyBeanRegistry(...)` → 
`BeanRegistryLookup`. The ~30+ marshalling-side callers that currently use the 
`ClassMeta`-returning getters need an audit — most will just inherit 
`BeanTypeInfo`/`ClassInfo` methods; some will need explicit `(ClassMeta<?>) 
pMeta.getClassMeta [...]
-  - **Phase C — `validate(...)` body lift-out.** 
`Builder.validate(MarshallingContext bc, ...)` reads `bc.resolveClassMeta(...)` 
/ `bc.object()`; those reads need to move to a marshalling-side post-processor 
(or a narrow `BeanSession` SPI) so the bean-modeling-side `validate` becomes 
pure (or split into a commons-side `validate()` and a marshalling-side 
`installTypeMetadata(...)`).
-  - **Phase C — Marshalling-side `BeanMeta` factory helper.** Move the body of 
`BeanMeta(BeanTypeInfo<T>, BeanFilter, String[], ClassInfo)` out to a 
marshalling-side helper that sets `classMeta` and `marshallingContext` via a 
setter on the commons-side `BeanMeta`. Alternatively, fold the marshalling-only 
fields (`classMeta`, `marshallingContext`) into a side-map keyed by `BeanMeta` 
instance.
-  - **Phase C — `JsonList`/`JsonMap` final cleanup (deferred from Phase A 
sub-item 10).** Flip `setPropertyValue`'s `new JsonList(valueList)` to `new 
ArrayList<>(valueList)`. This is test-observable: 
`BeanMap_Test.a05_arrayProperties`, `a06_arrayProperties_usingConfig`, 
`a09_beanPropertyAnnotation` assert that the resulting field's concrete class 
is `JsonList`. Either update the tests to expect `ArrayList` (preferred — the 
original `JsonList` choice was incidental, not contractual), or w [...]
-  - **Phase C sub-item 15 — Final cleanup.** `git mv` the 8 files into 
`juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/bean/`, 
update `package` declarations, repo-wide reference sweep (`import 
org.apache.juneau.BeanMap` → `import org.apache.juneau.commons.bean.BeanMap`, 
etc., plus `{@link …}` references in Javadoc), verify `cd 
juneau-core/juneau-commons && mvn clean compile` standalone passes, run 
`python3 scripts/test.py --full`.
+  - **Phase C Task 1 — Public API widen.** — DONE. See Phase C status block 
above. `BeanPropertyMeta.getClassMeta()` → `BeanTypeInfo<?>`, 
`BeanMeta.getClassMeta()` → `BeanTypeInfo<T>`, `BeanMeta.getBeanRegistry()` / 
`getPropertyBeanRegistry(...)` → `BeanRegistryLookup`, `BeanMap.getClassMeta()` 
→ `BeanTypeInfo<T>`. ~26 marshalling-side callers updated with explicit 
`(ClassMeta<?>)` / `(BeanRegistry)` casts at the call sites that invoke 
`ClassMeta`-only / `BeanRegistry`-only methods. Buil [...]
+  - **Phase C Task 2 — `validate(...)` body lift-out.** — DONE (signature 
seam). See Phase C status block above. New `BeanTypeResolver` SPI in 
`commons.bean`. `MarshallingContext` implements it. 
`Builder.validate(BeanTypeResolver bc, ...)` parameter retyped. 
`bc.resolveClassMeta(...)` → `bc.resolveType(...)`, `bc.object()` → 
`bc.objectType()`. Build + full test green. Note: three other marshalling-only 
seams on `BeanPropertyMeta` remain (Builder `rawMetaType(Class<?>)`, 
constructor `ap`  [...]
+  - **Phase C Task 3 — Marshalling-side `BeanMeta` factory helper.** — NOT 
STARTED. The `BeanMeta(BeanTypeInfo<T>, BeanFilter, String[], ClassInfo)` 
protected constructor still contains marshalling-layer-aware logic (cast back 
to `ClassMeta<T>` to read `getMarshallingContext()` / `getBeanConfigContext()`, 
builds swap-aware transforms, registers per-property `BeanRegistry`). Move the 
body of that constructor out to a marshalling-side helper that sets `classMeta` 
and `marshallingContext` v [...]
+  - **Phase C Task 4 — `JsonList`/`JsonMap` final cleanup.** — PARTIAL. Done: 
`setPropertyValue`'s `new JsonList(valueList)` flipped to `new 
ArrayList<>(valueList)` (typed-element abstract-Collection branch). Three test 
assertions updated. Pass-through behavior preserved for raw-`Object`-element 
collections (a03/a04 tests still green). Deferred (test-invisible at the moment 
but still marshalling-layer leaks): two `CharSequence`-handling sites inside 
`setPropertyValue` (`value1 = JsonMap. [...]
+  - **Phase C Task 5 — Physical `git mv` + reference sweep.** — NOT STARTED. 
Prerequisites: Phase C Tasks 2, 3, and the deferred Task 4 CharSequence-parsing 
sites. Before the move, the 8 files still need to drop their marshalling-side 
imports (`annotation.*`, `internal.*`, `collections.*`, `parser.*`, 
`serializer.*`, `swap.*`). After those are cleaned up, `git mv` the 8 files 
into 
`juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/bean/`, 
update `package` declarations, r [...]
 - [ ] **Step 8c** — (optional) Cleanup pass for anything that comes up during 
8b-ii: deprecated bridges, stale imports, package-info docs, etc.
 - [ ] **Step 9** — Reference sweep: 80–120 unique files (mostly inside 
`juneau-marshall`). Update imports, Javadoc `{@link …}` references, 
package-info docs.
 - [ ] **Step 10** — Update `juneau-docs` release notes / migration guide 
(`docs/pages/release-notes/9.5.0.md`, `## Package Moves` section) with the 
bean-runtime relocations.

Reply via email to