From 1c108054ee11bfbdd2516eaa45b3f912b29af22e Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Tue, 29 Apr 2025 11:47:09 +0200 Subject: [PATCH 1/2] Close ApplicationContext after AOT processing Closes gh-34841 --- .../context/aot/ContextAotProcessor.java | 7 ++++--- .../context/aot/ContextAotProcessorTests.java | 17 +++++++++++------ 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/spring-context/src/main/java/org/springframework/context/aot/ContextAotProcessor.java b/spring-context/src/main/java/org/springframework/context/aot/ContextAotProcessor.java index 16fbee9bb3a..746e23cfd6f 100644 --- a/spring-context/src/main/java/org/springframework/context/aot/ContextAotProcessor.java +++ b/spring-context/src/main/java/org/springframework/context/aot/ContextAotProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2022 the original author or authors. + * Copyright 2002-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -80,8 +80,9 @@ public abstract class ContextAotProcessor extends AbstractAotProcessor getDefaultNativeImageArguments(String application) { return Collections.emptyList(); } }; processor.process(); + assertThat(processor.context.isClosed()).isTrue(); assertThat(directory.resolve("resource/META-INF/native-image/com.example/example/native-image.properties")) .doesNotExist(); context.close(); @@ -118,6 +121,8 @@ class ContextAotProcessorTests { private static class DemoContextAotProcessor extends ContextAotProcessor { + AnnotationConfigApplicationContext context; + DemoContextAotProcessor(Class application, Path rootPath) { this(application, rootPath.resolve("source"), rootPath.resolve("resource"), rootPath.resolve("class")); } @@ -141,11 +146,12 @@ class ContextAotProcessorTests { protected GenericApplicationContext prepareApplicationContext(Class application) { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); context.register(application); + this.context = context; return context; } - } + @Configuration(proxyBeanMethods = false) static class SampleApplication { @@ -153,7 +159,6 @@ class ContextAotProcessorTests { public String testBean() { return "Hello"; } - } } From 03620fc53049a8f391d6938bc48cbd70414cbc92 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Tue, 29 Apr 2025 11:47:47 +0200 Subject: [PATCH 2/2] Polishing --- .../context/aot/ApplicationContextAotGenerator.java | 3 ++- .../aot/ReflectiveProcessorAotContributionBuilder.java | 5 +++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/spring-context/src/main/java/org/springframework/context/aot/ApplicationContextAotGenerator.java b/spring-context/src/main/java/org/springframework/context/aot/ApplicationContextAotGenerator.java index 0331b145c10..eb5c736fafb 100644 --- a/spring-context/src/main/java/org/springframework/context/aot/ApplicationContextAotGenerator.java +++ b/spring-context/src/main/java/org/springframework/context/aot/ApplicationContextAotGenerator.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2023 the original author or authors. + * Copyright 2002-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -50,6 +50,7 @@ public class ApplicationContextAotGenerator { */ public ClassName processAheadOfTime(GenericApplicationContext applicationContext, GenerationContext generationContext) { + return withCglibClassHandler(new CglibClassHandler(generationContext), () -> { applicationContext.refreshForAotProcessing(generationContext.getRuntimeHints()); ApplicationContextInitializationCodeGenerator codeGenerator = diff --git a/spring-context/src/main/java/org/springframework/context/aot/ReflectiveProcessorAotContributionBuilder.java b/spring-context/src/main/java/org/springframework/context/aot/ReflectiveProcessorAotContributionBuilder.java index 4b6a7b79182..d538a56ede3 100644 --- a/spring-context/src/main/java/org/springframework/context/aot/ReflectiveProcessorAotContributionBuilder.java +++ b/spring-context/src/main/java/org/springframework/context/aot/ReflectiveProcessorAotContributionBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2024 the original author or authors. + * Copyright 2002-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -100,6 +100,7 @@ public class ReflectiveProcessorAotContributionBuilder { return (!this.classes.isEmpty() ? new AotContribution(this.classes) : null); } + private static class AotContribution implements BeanFactoryInitializationAotContribution { private final Class[] classes; @@ -113,9 +114,9 @@ public class ReflectiveProcessorAotContributionBuilder { RuntimeHints runtimeHints = generationContext.getRuntimeHints(); registrar.registerRuntimeHints(runtimeHints, this.classes); } - } + private static class ReflectiveClassPathScanner extends ClassPathScanningCandidateComponentProvider { @Nullable