From c7ffb1cd49ba03d0d39a252a579d4b8660eac02a Mon Sep 17 00:00:00 2001 From: Oleg Zhurakousky Date: Fri, 1 Oct 2021 10:16:52 +0200 Subject: [PATCH] GH-747 Fix Kotlin function bootstrapping in AWS adapter Resolves #747 --- .../function/utils/FunctionClassUtils.java | 22 +++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/utils/FunctionClassUtils.java b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/utils/FunctionClassUtils.java index 09ba0725d..18f60737b 100644 --- a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/utils/FunctionClassUtils.java +++ b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/utils/FunctionClassUtils.java @@ -28,6 +28,9 @@ import org.apache.commons.logging.LogFactory; import org.springframework.boot.SpringBootConfiguration; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.core.KotlinDetector; +import org.springframework.core.io.Resource; +import org.springframework.core.io.support.PathMatchingResourcePatternResolver; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; import org.springframework.util.StringUtils; @@ -109,7 +112,22 @@ public final class FunctionClassUtils { if (StringUtils.hasText(startClassName)) { Class startClass = ClassUtils.forName(startClassName, classLoader); - if (isSpringBootApplication(startClass)) { + + if (KotlinDetector.isKotlinType(startClass)) { + PathMatchingResourcePatternResolver r = new PathMatchingResourcePatternResolver(classLoader); + String packageName = startClass.getPackage().getName(); + Resource[] resources = r.getResources("classpath:" + packageName.replace(".", "/") + "/*.class"); + for (int i = 0; i < resources.length; i++) { + Resource resource = resources[i]; + String className = packageName + "." + (resource.getFilename().replace("/", ".")).replace(".class", ""); + startClass = ClassUtils.forName(className, classLoader); + if (isSpringBootApplication(startClass, classLoader)) { + logger.info("Loaded Main Kotlin Class: " + startClass); + return startClass; + } + } + } + else if (isSpringBootApplication(startClass, classLoader)) { logger.info("Loaded Start Class: " + startClass); return startClass; } @@ -128,7 +146,7 @@ public final class FunctionClassUtils { return null; } - private static boolean isSpringBootApplication(Class startClass) { + private static boolean isSpringBootApplication(Class startClass, ClassLoader loader) { return startClass.getDeclaredAnnotation(SpringBootApplication.class) != null || startClass.getDeclaredAnnotation(SpringBootConfiguration.class) != null; }