diff --git a/pom.xml b/pom.xml index 0fd4f3b212..bdc2b03e6d 100644 --- a/pom.xml +++ b/pom.xml @@ -60,9 +60,10 @@ 1.21 2.11.0 1.15 - 2.7.4 + 3.0.0-M5 5.3.23 0.15.0 + 0.10.2 true @@ -89,6 +90,11 @@ + + org.reflections + reflections + ${reflections.version} + org.apache.commons commons-lang3 @@ -324,7 +330,16 @@ default - + + + spring-milestones + Spring Milestones + https://repo.spring.io/milestone + + false + + + @@ -393,21 +408,21 @@ - - + + org.apache.maven.plugins maven-source-plugin 3.2.1 - - attach-sources - - jar-no-fork - - + + attach-sources + + jar-no-fork + + - - + + org.apache.maven.plugins maven-assembly-plugin 3.4.2 @@ -489,35 +504,35 @@ -/* -Copyright $YEAR The Kubernetes 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 -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. -*/ + /* + Copyright $YEAR The Kubernetes 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 + 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. + */ -/* -Copyright $YEAR The Kubernetes 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 -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. -*/ + /* + Copyright $YEAR The Kubernetes 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 + 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 @@ -525,7 +540,6 @@ limitations under the License. - release-sign-artifacts @@ -541,8 +555,8 @@ limitations under the License. verify sign - - + + --pinentry-mode @@ -562,4 +576,4 @@ limitations under the License. - + \ No newline at end of file diff --git a/spring/pom.xml b/spring/pom.xml index 93cb0df61a..b22d731250 100644 --- a/spring/pom.xml +++ b/spring/pom.xml @@ -14,8 +14,11 @@ ../pom.xml - + + org.reflections + reflections + io.kubernetes client-java-api @@ -26,7 +29,6 @@ client-java-extended ${project.version} - org.springframework.boot spring-boot diff --git a/spring/src/main/java/io/kubernetes/client/spring/extended/controller/config/KubernetesReconcilerAutoConfiguration.java b/spring/src/main/java/io/kubernetes/client/spring/extended/controller/config/KubernetesReconcilerAutoConfiguration.java index f59f66c311..45627feb36 100644 --- a/spring/src/main/java/io/kubernetes/client/spring/extended/controller/config/KubernetesReconcilerAutoConfiguration.java +++ b/spring/src/main/java/io/kubernetes/client/spring/extended/controller/config/KubernetesReconcilerAutoConfiguration.java @@ -17,7 +17,7 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -@Configuration(proxyBeanMethods = false) +@Configuration @ConditionalOnKubernetesReconcilerEnabled public class KubernetesReconcilerAutoConfiguration { diff --git a/spring/src/main/java/io/kubernetes/client/spring/extended/controller/config/aot/KubernetesBeanFactoryInitializationAotProcessor.java b/spring/src/main/java/io/kubernetes/client/spring/extended/controller/config/aot/KubernetesBeanFactoryInitializationAotProcessor.java new file mode 100644 index 0000000000..400a4309df --- /dev/null +++ b/spring/src/main/java/io/kubernetes/client/spring/extended/controller/config/aot/KubernetesBeanFactoryInitializationAotProcessor.java @@ -0,0 +1,88 @@ +package io.kubernetes.client.spring.extended.controller.config.aot; + + +import com.google.gson.JsonElement; +import com.google.gson.annotations.JsonAdapter; +import io.kubernetes.client.informer.cache.ProcessorListener; +import io.kubernetes.client.util.Watch; +import io.kubernetes.client.util.generic.GenericKubernetesApi; +import io.swagger.annotations.ApiModel; +import org.jetbrains.annotations.NotNull; +import org.reflections.Reflections; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.aot.hint.MemberCategory; +import org.springframework.aot.hint.RuntimeHints; +import org.springframework.aot.hint.TypeReference; +import org.springframework.beans.factory.aot.BeanFactoryInitializationAotContribution; +import org.springframework.beans.factory.aot.BeanFactoryInitializationAotProcessor; +import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; +import org.springframework.boot.autoconfigure.AutoConfigurationPackages; + +import java.lang.annotation.Annotation; +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; + +/** + * Registers hints to support Spring Framework 6 and Spring Boot 3 AOT + */ +public class KubernetesBeanFactoryInitializationAotProcessor implements BeanFactoryInitializationAotProcessor { + + private static final Logger LOGGER = LoggerFactory.getLogger(KubernetesBeanFactoryInitializationAotProcessor.class); + + private final MemberCategory[] allMemberCategories = MemberCategory.values(); + + @Override + public BeanFactoryInitializationAotContribution processAheadOfTime( + @NotNull ConfigurableListableBeanFactory beanFactory) { + return (generationContext, beanFactoryInitializationCode) -> { + RuntimeHints hints = generationContext.getRuntimeHints(); + Class[] classes = new Class[]{JsonElement.class, ProcessorListener.class, + io.kubernetes.client.extended.controller.Controller.class, + GenericKubernetesApi.StatusPatch.class, Watch.Response.class + }; + for (Class clazz : classes) { + logClassReflectionRegistration(clazz); + hints.reflection().registerType(TypeReference.of(clazz), allMemberCategories); + } + registerForPackage("io.kubernetes", hints); + Collection packages = AutoConfigurationPackages.get(beanFactory); + for (String packageName : packages) { + registerForPackage(packageName, hints); + } + }; + } + + private void registerForPackage(String packageName, RuntimeHints hints) { + Reflections reflections = new Reflections(packageName); + Set> apiModels = reflections.getTypesAnnotatedWith(ApiModel.class); + Set> jsonAdapters = findJsonAdapters(reflections); + Set> all = new HashSet<>(); + all.addAll(jsonAdapters); + all.addAll(apiModels); + for (Class clazz : all) { + logClassReflectionRegistration(clazz); + hints.reflection().registerType(clazz, allMemberCategories); + } + } + + private static void logClassReflectionRegistration(Class clazz) { + if (LOGGER.isInfoEnabled()) { + LOGGER.info("registering " + clazz.getName() + " for Spring AOT reflection"); + } + } + + private Set> findJsonAdapters(Reflections reflections) { + Class jsonAdapterClass = JsonAdapter.class; + Set> classes = new HashSet<>(); + for (Class clazz : reflections.getTypesAnnotatedWith(jsonAdapterClass)) { + JsonAdapter annotation = clazz.getAnnotation(jsonAdapterClass); + if (null != annotation) { + classes.add(annotation.value()); + } + classes.add(clazz); + } + return classes; + } +} \ No newline at end of file diff --git a/spring/src/main/resources/META-INF/spring/aot.factories b/spring/src/main/resources/META-INF/spring/aot.factories new file mode 100644 index 0000000000..ffb354197e --- /dev/null +++ b/spring/src/main/resources/META-INF/spring/aot.factories @@ -0,0 +1 @@ +org.springframework.beans.factory.aot.BeanFactoryInitializationAotProcessor=io.kubernetes.client.spring.extended.controller.config.aot.KubernetesBeanFactoryInitializationAotProcessor \ No newline at end of file diff --git a/spring/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 0000000000..7e78a1ccfa --- /dev/null +++ b/spring/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1,3 @@ +io.kubernetes.client.spring.extended.controller.config.KubernetesInformerAutoConfiguration +io.kubernetes.client.spring.extended.controller.config.KubernetesReconcilerAutoConfiguration +io.kubernetes.client.spring.extended.manifests.config.KubernetesManifestsAutoConfiguration \ No newline at end of file