From 6effd6061cfa8859c5135d0983c3757f7b8540b1 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Thu, 29 Jun 2023 18:09:30 +0100 Subject: [PATCH] Provide hints when template auto-config is excluded Fixes gh-35682 --- .../FreeMarkerAutoConfiguration.java | 4 +-- .../freemarker/FreeMarkerRuntimeHints.java | 34 ------------------- ...reeMarkerTemplateAvailabilityProvider.java | 24 +++++++++++-- .../GroovyTemplateAutoConfiguration.java | 2 -- .../GroovyTemplateAvailabilityProvider.java | 24 +++++++++++-- .../template/GroovyTemplateRuntimeHints.java | 34 ------------------- .../resources/META-INF/spring/aot.factories | 2 ++ ...rkerTemplateAvailabilityProviderTests.java | 16 +++++++++ ...oovyTemplateAvailabilityProviderTests.java | 16 +++++++++ 9 files changed, 79 insertions(+), 77 deletions(-) delete mode 100644 spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/freemarker/FreeMarkerRuntimeHints.java delete mode 100644 spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/groovy/template/GroovyTemplateRuntimeHints.java diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/freemarker/FreeMarkerAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/freemarker/FreeMarkerAutoConfiguration.java index 29403ecf5b7..254d8d7d4a2 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/freemarker/FreeMarkerAutoConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/freemarker/FreeMarkerAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2023 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. @@ -29,7 +29,6 @@ import org.springframework.boot.autoconfigure.template.TemplateLocation; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Import; -import org.springframework.context.annotation.ImportRuntimeHints; import org.springframework.ui.freemarker.FreeMarkerConfigurationFactory; /** @@ -45,7 +44,6 @@ import org.springframework.ui.freemarker.FreeMarkerConfigurationFactory; @EnableConfigurationProperties(FreeMarkerProperties.class) @Import({ FreeMarkerServletWebConfiguration.class, FreeMarkerReactiveWebConfiguration.class, FreeMarkerNonWebConfiguration.class }) -@ImportRuntimeHints(FreeMarkerRuntimeHints.class) public class FreeMarkerAutoConfiguration { private static final Log logger = LogFactory.getLog(FreeMarkerAutoConfiguration.class); diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/freemarker/FreeMarkerRuntimeHints.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/freemarker/FreeMarkerRuntimeHints.java deleted file mode 100644 index 737504998f3..00000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/freemarker/FreeMarkerRuntimeHints.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2012-2022 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. - * You may obtain a copy of the License at - * - * https://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.springframework.boot.autoconfigure.freemarker; - -import org.springframework.aot.hint.RuntimeHintsRegistrar; -import org.springframework.boot.autoconfigure.freemarker.FreeMarkerTemplateAvailabilityProvider.FreeMarkerTemplateAvailabilityProperties; -import org.springframework.boot.context.properties.bind.BindableRuntimeHintsRegistrar; - -/** - * {@link RuntimeHintsRegistrar} for FreeMarker support. - * - * @author Moritz Halbritter - */ -class FreeMarkerRuntimeHints extends BindableRuntimeHintsRegistrar { - - FreeMarkerRuntimeHints() { - super(FreeMarkerTemplateAvailabilityProperties.class); - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/freemarker/FreeMarkerTemplateAvailabilityProvider.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/freemarker/FreeMarkerTemplateAvailabilityProvider.java index 8d2e290e67e..4209bca7c9a 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/freemarker/FreeMarkerTemplateAvailabilityProvider.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/freemarker/FreeMarkerTemplateAvailabilityProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-2023 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. @@ -20,8 +20,11 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import org.springframework.aot.hint.RuntimeHints; import org.springframework.boot.autoconfigure.template.PathBasedTemplateAvailabilityProvider; import org.springframework.boot.autoconfigure.template.TemplateAvailabilityProvider; +import org.springframework.boot.context.properties.bind.BindableRuntimeHintsRegistrar; +import org.springframework.util.ClassUtils; /** * {@link TemplateAvailabilityProvider} that provides availability information for @@ -32,8 +35,10 @@ import org.springframework.boot.autoconfigure.template.TemplateAvailabilityProvi */ public class FreeMarkerTemplateAvailabilityProvider extends PathBasedTemplateAvailabilityProvider { + private static final String REQUIRED_CLASS_NAME = "freemarker.template.Configuration"; + public FreeMarkerTemplateAvailabilityProvider() { - super("freemarker.template.Configuration", FreeMarkerTemplateAvailabilityProperties.class, "spring.freemarker"); + super(REQUIRED_CLASS_NAME, FreeMarkerTemplateAvailabilityProperties.class, "spring.freemarker"); } protected static final class FreeMarkerTemplateAvailabilityProperties extends TemplateAvailabilityProperties { @@ -60,4 +65,19 @@ public class FreeMarkerTemplateAvailabilityProvider extends PathBasedTemplateAva } + static class FreeMarkerTemplateAvailabilityRuntimeHints extends BindableRuntimeHintsRegistrar { + + FreeMarkerTemplateAvailabilityRuntimeHints() { + super(FreeMarkerTemplateAvailabilityProperties.class); + } + + @Override + public void registerHints(RuntimeHints hints, ClassLoader classLoader) { + if (ClassUtils.isPresent(REQUIRED_CLASS_NAME, classLoader)) { + super.registerHints(hints, classLoader); + } + } + + } + } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/groovy/template/GroovyTemplateAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/groovy/template/GroovyTemplateAutoConfiguration.java index bb5403b4133..fe1b9dea280 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/groovy/template/GroovyTemplateAutoConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/groovy/template/GroovyTemplateAutoConfiguration.java @@ -38,7 +38,6 @@ import org.springframework.boot.context.properties.EnableConfigurationProperties import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.ImportRuntimeHints; import org.springframework.context.i18n.LocaleContextHolder; import org.springframework.core.log.LogMessage; import org.springframework.web.servlet.view.UrlBasedViewResolver; @@ -60,7 +59,6 @@ import org.springframework.web.servlet.view.groovy.GroovyMarkupViewResolver; @AutoConfiguration(after = WebMvcAutoConfiguration.class) @ConditionalOnClass(MarkupTemplateEngine.class) @EnableConfigurationProperties(GroovyTemplateProperties.class) -@ImportRuntimeHints(GroovyTemplateRuntimeHints.class) public class GroovyTemplateAutoConfiguration { private static final Log logger = LogFactory.getLog(GroovyTemplateAutoConfiguration.class); diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/groovy/template/GroovyTemplateAvailabilityProvider.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/groovy/template/GroovyTemplateAvailabilityProvider.java index 22b6575da3d..ae67f961a15 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/groovy/template/GroovyTemplateAvailabilityProvider.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/groovy/template/GroovyTemplateAvailabilityProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-2023 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. @@ -20,8 +20,11 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import org.springframework.aot.hint.RuntimeHints; import org.springframework.boot.autoconfigure.template.PathBasedTemplateAvailabilityProvider; import org.springframework.boot.autoconfigure.template.TemplateAvailabilityProvider; +import org.springframework.boot.context.properties.bind.BindableRuntimeHintsRegistrar; +import org.springframework.util.ClassUtils; /** * {@link TemplateAvailabilityProvider} that provides availability information for Groovy @@ -32,8 +35,10 @@ import org.springframework.boot.autoconfigure.template.TemplateAvailabilityProvi */ public class GroovyTemplateAvailabilityProvider extends PathBasedTemplateAvailabilityProvider { + private static final String REQUIRED_CLASS_NAME = "groovy.text.TemplateEngine"; + public GroovyTemplateAvailabilityProvider() { - super("groovy.text.TemplateEngine", GroovyTemplateAvailabilityProperties.class, "spring.groovy.template"); + super(REQUIRED_CLASS_NAME, GroovyTemplateAvailabilityProperties.class, "spring.groovy.template"); } protected static final class GroovyTemplateAvailabilityProperties extends TemplateAvailabilityProperties { @@ -60,4 +65,19 @@ public class GroovyTemplateAvailabilityProvider extends PathBasedTemplateAvailab } + static class GroovyTemplateAvailabilityRuntimeHints extends BindableRuntimeHintsRegistrar { + + GroovyTemplateAvailabilityRuntimeHints() { + super(GroovyTemplateAvailabilityProperties.class); + } + + @Override + public void registerHints(RuntimeHints hints, ClassLoader classLoader) { + if (ClassUtils.isPresent(REQUIRED_CLASS_NAME, classLoader)) { + super.registerHints(hints, classLoader); + } + } + + } + } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/groovy/template/GroovyTemplateRuntimeHints.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/groovy/template/GroovyTemplateRuntimeHints.java deleted file mode 100644 index 92432553605..00000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/groovy/template/GroovyTemplateRuntimeHints.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2012-2023 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. - * You may obtain a copy of the License at - * - * https://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.springframework.boot.autoconfigure.groovy.template; - -import org.springframework.aot.hint.RuntimeHintsRegistrar; -import org.springframework.boot.autoconfigure.groovy.template.GroovyTemplateAvailabilityProvider.GroovyTemplateAvailabilityProperties; -import org.springframework.boot.context.properties.bind.BindableRuntimeHintsRegistrar; - -/** - * {@link RuntimeHintsRegistrar} for Groovy Template support. - * - * @author Moritz Halbritter - */ -class GroovyTemplateRuntimeHints extends BindableRuntimeHintsRegistrar { - - GroovyTemplateRuntimeHints() { - super(GroovyTemplateAvailabilityProperties.class); - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/resources/META-INF/spring/aot.factories b/spring-boot-project/spring-boot-autoconfigure/src/main/resources/META-INF/spring/aot.factories index 17134456182..80ce2b10358 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/resources/META-INF/spring/aot.factories +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/resources/META-INF/spring/aot.factories @@ -1,4 +1,6 @@ org.springframework.aot.hint.RuntimeHintsRegistrar=\ +org.springframework.boot.autoconfigure.freemarker.FreeMarkerTemplateAvailabilityProvider.FreeMarkerTemplateAvailabilityRuntimeHints,\ +org.springframework.boot.autoconfigure.groovy.template.GroovyTemplateAvailabilityProvider.GroovyTemplateAvailabilityRuntimeHints,\ org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration.JacksonAutoConfigurationRuntimeHints,\ org.springframework.boot.autoconfigure.template.TemplateRuntimeHints diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/freemarker/FreeMarkerTemplateAvailabilityProviderTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/freemarker/FreeMarkerTemplateAvailabilityProviderTests.java index 897c888f623..d39f11fb8bb 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/freemarker/FreeMarkerTemplateAvailabilityProviderTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/freemarker/FreeMarkerTemplateAvailabilityProviderTests.java @@ -18,6 +18,12 @@ package org.springframework.boot.autoconfigure.freemarker; import org.junit.jupiter.api.Test; +import org.springframework.aot.hint.RuntimeHints; +import org.springframework.aot.hint.RuntimeHintsRegistrar; +import org.springframework.aot.hint.TypeHint; +import org.springframework.beans.factory.aot.AotServices; +import org.springframework.boot.autoconfigure.freemarker.FreeMarkerTemplateAvailabilityProvider.FreeMarkerTemplateAvailabilityProperties; +import org.springframework.boot.autoconfigure.freemarker.FreeMarkerTemplateAvailabilityProvider.FreeMarkerTemplateAvailabilityRuntimeHints; import org.springframework.boot.autoconfigure.template.TemplateAvailabilityProvider; import org.springframework.core.io.DefaultResourceLoader; import org.springframework.core.io.ResourceLoader; @@ -84,4 +90,14 @@ class FreeMarkerTemplateAvailabilityProviderTests { .isTrue(); } + @Test + void shouldRegisterFreeMarkerTemplateAvailabilityPropertiesRuntimeHints() { + assertThat(AotServices.factories().load(RuntimeHintsRegistrar.class)) + .hasAtLeastOneElementOfType(FreeMarkerTemplateAvailabilityRuntimeHints.class); + RuntimeHints hints = new RuntimeHints(); + new FreeMarkerTemplateAvailabilityRuntimeHints().registerHints(hints, getClass().getClassLoader()); + TypeHint typeHint = hints.reflection().getTypeHint(FreeMarkerTemplateAvailabilityProperties.class); + assertThat(typeHint).isNotNull(); + } + } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/groovy/template/GroovyTemplateAvailabilityProviderTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/groovy/template/GroovyTemplateAvailabilityProviderTests.java index 70849ec7518..86c0158471e 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/groovy/template/GroovyTemplateAvailabilityProviderTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/groovy/template/GroovyTemplateAvailabilityProviderTests.java @@ -18,6 +18,12 @@ package org.springframework.boot.autoconfigure.groovy.template; import org.junit.jupiter.api.Test; +import org.springframework.aot.hint.RuntimeHints; +import org.springframework.aot.hint.RuntimeHintsRegistrar; +import org.springframework.aot.hint.TypeHint; +import org.springframework.beans.factory.aot.AotServices; +import org.springframework.boot.autoconfigure.groovy.template.GroovyTemplateAvailabilityProvider.GroovyTemplateAvailabilityProperties; +import org.springframework.boot.autoconfigure.groovy.template.GroovyTemplateAvailabilityProvider.GroovyTemplateAvailabilityRuntimeHints; import org.springframework.boot.autoconfigure.template.TemplateAvailabilityProvider; import org.springframework.core.io.DefaultResourceLoader; import org.springframework.core.io.ResourceLoader; @@ -84,4 +90,14 @@ class GroovyTemplateAvailabilityProviderTests { .isTrue(); } + @Test + void shouldRegisterGroovyTemplateAvailabilityPropertiesRuntimeHints() { + assertThat(AotServices.factories().load(RuntimeHintsRegistrar.class)) + .hasAtLeastOneElementOfType(GroovyTemplateAvailabilityRuntimeHints.class); + RuntimeHints hints = new RuntimeHints(); + new GroovyTemplateAvailabilityRuntimeHints().registerHints(hints, getClass().getClassLoader()); + TypeHint typeHint = hints.reflection().getTypeHint(GroovyTemplateAvailabilityProperties.class); + assertThat(typeHint).isNotNull(); + } + }