From ea0fe71e1d2f9370534d8b74c5e60f900c4b39e0 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 6 Mar 2026 18:56:48 +0000 Subject: [PATCH 1/2] Initial plan From 3adc713c7b81d68ec86b10dcae11986087c822bd Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 6 Mar 2026 19:06:30 +0000 Subject: [PATCH 2/2] Add classLoader() to MorphiaConfig and remove no-arg CritterClassLoader constructor Co-authored-by: evanchooly <195021+evanchooly@users.noreply.github.com> --- .../morphia/config/ManualMorphiaConfig.java | 7 ++++++ .../dev/morphia/config/MorphiaConfig.java | 24 +++++++++++++++++++ .../morphia/critter/CritterClassLoader.java | 4 ---- .../dev/morphia/mapping/AbstractMapper.java | 2 +- .../morphia/critter/parser/GeneratorTest.java | 2 +- .../critter/parser/TestAccessorsMutators.java | 2 +- .../parser/TestEntityModelGenerator.java | 2 +- .../parser/TestPropertyModelGenerator.java | 2 +- .../critter/parser/TestVarHandleAccessor.java | 2 +- .../parser/gizmo/TestGizmoGeneration.java | 4 ++-- 10 files changed, 39 insertions(+), 12 deletions(-) diff --git a/core/src/main/java/dev/morphia/config/ManualMorphiaConfig.java b/core/src/main/java/dev/morphia/config/ManualMorphiaConfig.java index edda8f41469..042087f4ce3 100644 --- a/core/src/main/java/dev/morphia/config/ManualMorphiaConfig.java +++ b/core/src/main/java/dev/morphia/config/ManualMorphiaConfig.java @@ -35,6 +35,7 @@ public class ManualMorphiaConfig implements MorphiaConfig { Boolean applyCaps; Boolean applyDocumentValidations; Boolean applyIndexes; + ClassLoader classLoader; Optional codecProvider; @@ -69,6 +70,7 @@ public ManualMorphiaConfig(MorphiaConfig base) { applyCaps = base.applyCaps(); applyDocumentValidations = base.applyDocumentValidations(); applyIndexes = base.applyIndexes(); + classLoader = base.classLoader(); codecProvider = base.codecProvider(); collectionNaming = base.collectionNaming(); database = base.database(); @@ -122,6 +124,11 @@ public Boolean applyCaps() { return orDefault(applyCaps, FALSE); } + @Override + public ClassLoader classLoader() { + return orDefault(classLoader, Thread.currentThread().getContextClassLoader()); + } + public Boolean applyDocumentValidations() { return orDefault(applyDocumentValidations, FALSE); } diff --git a/core/src/main/java/dev/morphia/config/MorphiaConfig.java b/core/src/main/java/dev/morphia/config/MorphiaConfig.java index c079dc40723..d230fcaea84 100644 --- a/core/src/main/java/dev/morphia/config/MorphiaConfig.java +++ b/core/src/main/java/dev/morphia/config/MorphiaConfig.java @@ -48,6 +48,30 @@ @ConfigMapping(prefix = "morphia") public interface MorphiaConfig { + /** + * The classloader to use for class lookups and bytecode generation. + * + * @return the configured classloader + * @since 3.0 + */ + default ClassLoader classLoader() { + return Thread.currentThread().getContextClassLoader(); + } + + /** + * Updates this configuration with a new value and returns a new instance. The original instance is unchanged. + * + * @param value the new value + * @return a new instance with the updated configuration + * @since 3.0 + */ + default MorphiaConfig classLoader(ClassLoader value) { + var newConfig = new ManualMorphiaConfig(this); + + newConfig.classLoader = value; + return newConfig; + } + /** * Tries to load a configuration from the default location. * diff --git a/core/src/main/java/dev/morphia/critter/CritterClassLoader.java b/core/src/main/java/dev/morphia/critter/CritterClassLoader.java index 94f34c1ecbd..bdd675571c9 100644 --- a/core/src/main/java/dev/morphia/critter/CritterClassLoader.java +++ b/core/src/main/java/dev/morphia/critter/CritterClassLoader.java @@ -12,10 +12,6 @@ public CritterClassLoader(ClassLoader parent) { super(parent, Collections.emptyMap()); } - public CritterClassLoader() { - this(Thread.currentThread().getContextClassLoader()); - } - public void register(String name, byte[] bytes) { typeDefinitions.put(name, bytes); } diff --git a/core/src/main/java/dev/morphia/mapping/AbstractMapper.java b/core/src/main/java/dev/morphia/mapping/AbstractMapper.java index 8e4cc5351cc..0ea5b47240b 100644 --- a/core/src/main/java/dev/morphia/mapping/AbstractMapper.java +++ b/core/src/main/java/dev/morphia/mapping/AbstractMapper.java @@ -64,7 +64,7 @@ public abstract class AbstractMapper implements Mapper { @MorphiaInternal protected AbstractMapper(MorphiaConfig config) { this.config = config; - this.contextClassLoader = Thread.currentThread().getContextClassLoader(); + this.contextClassLoader = config.classLoader(); this.discriminatorLookup = new DiscriminatorLookup(); } diff --git a/core/src/test/java/dev/morphia/critter/parser/GeneratorTest.java b/core/src/test/java/dev/morphia/critter/parser/GeneratorTest.java index 60de63c366a..f8d41d62587 100644 --- a/core/src/test/java/dev/morphia/critter/parser/GeneratorTest.java +++ b/core/src/test/java/dev/morphia/critter/parser/GeneratorTest.java @@ -23,7 +23,7 @@ public class GeneratorTest { public static final CritterEntityModel entityModel; - public static final CritterClassLoader critterClassLoader = new CritterClassLoader(); + public static final CritterClassLoader critterClassLoader = new CritterClassLoader(Thread.currentThread().getContextClassLoader()); static { ClassGraph classGraph = new ClassGraph() diff --git a/core/src/test/java/dev/morphia/critter/parser/TestAccessorsMutators.java b/core/src/test/java/dev/morphia/critter/parser/TestAccessorsMutators.java index 6b076c81142..c045a96a9df 100644 --- a/core/src/test/java/dev/morphia/critter/parser/TestAccessorsMutators.java +++ b/core/src/test/java/dev/morphia/critter/parser/TestAccessorsMutators.java @@ -11,7 +11,7 @@ import org.testng.annotations.DataProvider; public class TestAccessorsMutators extends BaseCritterTest { - private final CritterClassLoader critterClassLoader = new CritterClassLoader(); + private final CritterClassLoader critterClassLoader = new CritterClassLoader(Thread.currentThread().getContextClassLoader()); // @Test(dataProvider = "classes") public void testPropertyAccessors(Class type) throws Exception { diff --git a/core/src/test/java/dev/morphia/critter/parser/TestEntityModelGenerator.java b/core/src/test/java/dev/morphia/critter/parser/TestEntityModelGenerator.java index 1d8e90fdc89..c51ce3c120c 100644 --- a/core/src/test/java/dev/morphia/critter/parser/TestEntityModelGenerator.java +++ b/core/src/test/java/dev/morphia/critter/parser/TestEntityModelGenerator.java @@ -20,7 +20,7 @@ public class TestEntityModelGenerator { private final CritterEntityModel control; private final Mapper mapper = new ReflectiveMapper(new ManualMorphiaConfig()); - private final CritterClassLoader critterClassLoader = new CritterClassLoader(); + private final CritterClassLoader critterClassLoader = new CritterClassLoader(Thread.currentThread().getContextClassLoader()); public TestEntityModelGenerator() { CritterEntityModel tmp; diff --git a/core/src/test/java/dev/morphia/critter/parser/TestPropertyModelGenerator.java b/core/src/test/java/dev/morphia/critter/parser/TestPropertyModelGenerator.java index f6b99c4d4dc..4ee8e6115cc 100644 --- a/core/src/test/java/dev/morphia/critter/parser/TestPropertyModelGenerator.java +++ b/core/src/test/java/dev/morphia/critter/parser/TestPropertyModelGenerator.java @@ -14,7 +14,7 @@ import org.testng.annotations.NoInjection; public class TestPropertyModelGenerator extends BaseCritterTest { - private final CritterClassLoader critterClassLoader = new CritterClassLoader(); + private final CritterClassLoader critterClassLoader = new CritterClassLoader(Thread.currentThread().getContextClassLoader()); // @Test(dataProvider = "properties", testName = "") public void testProperty(String control, String methodName, @NoInjection Method method) throws Exception { diff --git a/core/src/test/java/dev/morphia/critter/parser/TestVarHandleAccessor.java b/core/src/test/java/dev/morphia/critter/parser/TestVarHandleAccessor.java index 6b2d82ec049..97c07a989ea 100644 --- a/core/src/test/java/dev/morphia/critter/parser/TestVarHandleAccessor.java +++ b/core/src/test/java/dev/morphia/critter/parser/TestVarHandleAccessor.java @@ -22,7 +22,7 @@ public class TestVarHandleAccessor { @BeforeClass public void setup() { - classLoader = new CritterClassLoader(); + classLoader = new CritterClassLoader(Thread.currentThread().getContextClassLoader()); MorphiaConfig config = new ManualMorphiaConfig(); CritterGizmoGenerator.generate(Example.class, classLoader, new Generators(config, new ReflectiveMapper(config)), true); } diff --git a/core/src/test/java/dev/morphia/critter/parser/gizmo/TestGizmoGeneration.java b/core/src/test/java/dev/morphia/critter/parser/gizmo/TestGizmoGeneration.java index 8896d9c2913..e30489ae6a6 100644 --- a/core/src/test/java/dev/morphia/critter/parser/gizmo/TestGizmoGeneration.java +++ b/core/src/test/java/dev/morphia/critter/parser/gizmo/TestGizmoGeneration.java @@ -48,7 +48,7 @@ import static io.quarkus.gizmo.MethodDescriptor.ofMethod; public class TestGizmoGeneration { - private final CritterClassLoader critterClassLoader = new CritterClassLoader(); + private final CritterClassLoader critterClassLoader = new CritterClassLoader(Thread.currentThread().getContextClassLoader()); @Test public void testMapStringExample() { @@ -262,7 +262,7 @@ public void testConstructors() throws Exception { @Test public void testMethodBasedAccessors() throws Exception { - CritterClassLoader classLoader = new CritterClassLoader(); + CritterClassLoader classLoader = new CritterClassLoader(Thread.currentThread().getContextClassLoader()); String resourceName = MethodExample.class.getName().replace('.', '/') + ".class"; var inputStream = MethodExample.class.getClassLoader().getResourceAsStream(resourceName);