Kotlin+Spring Cloud Function部署AWS Lambda报No function defined问题咨询
问题根因
- 核心问题是application.yml配置未被正确加载:日志输出
No active profile set说明Spring上下文没有读取到你的配置文件,自然也无法识别spring.cloud.function.definition=greet的配置,所以即使greet Bean创建成功,Spring Cloud Function也不知道要绑定哪个Bean作为执行入口,最终抛出No function defined异常。 - Java版本运行正常、Kotlin版本异常的差异来自打包逻辑:你当前的shadowJar配置适配了Java Spring Boot项目的类加载逻辑,但Kotlin编译打包后,配置文件在shadowJar中的存储位置不符合AWS Lambda适配器的读取预期,加上部分版本Spring Cloud Function对Kotlin默认的函数式Bean类型识别存在兼容问题,共同导致了故障。
解决方案
步骤1:调整shadowJar打包配置,确保资源文件可被读取
修改build.gradle.kts中的ShadowJar配置,将编译后的类和配置文件提升到Jar包根目录,适配AWS Lambda的类加载规则:
tasks.withType<ShadowJar> { archiveClassifier.set("aws") archiveFileName.set("swaves.jar") dependencies { exclude( dependency("org.springframework.cloud:spring-cloud-function-web:3.1.3")) } // Required for Spring mergeServiceFiles() append("META-INF/spring.handlers") append ("META-INF/spring.schemas") append("META-INF/spring.tooling") transform(PropertiesFileTransformer::class.java) { val paths = arrayOf("META-INF/spring.factories") val mergeStrategy = "append" } // 新增以下配置,把类和资源文件移到Jar根目录 from("${buildDir}/classes/java/main") from("${buildDir}/classes/kotlin/main") from("${buildDir}/resources/main") }
打包完成后可以手动解压Jar包,确认根目录存在application.yml文件即可。
步骤2:通过Lambda环境变量强制指定核心配置(推荐)
在AWS Lambda控制台的环境变量配置页添加两个变量,优先级高于配置文件,即使配置文件读取异常也能保证配置生效:
SPRING_PROFILES_ACTIVE=productionSPRING_CLOUD_FUNCTION_DEFINITION=greet
步骤3:显式声明函数Bean类型,解决Kotlin类型兼容问题
部分版本Spring Cloud Function对Kotlin默认的lambda函数类型识别有误,可以将Bean显式声明为Java Function接口类型:
package com.aio.swaves import org.springframework.boot.autoconfigure.SpringBootApplication import org.springframework.boot.runApplication import org.springframework.context.annotation.Bean import java.util.function.Function @SpringBootApplication class SwavesApplication { @Bean fun greet(): Function<String, String> { return Function { "Hello Kotlin" } } } fun main(args: Array<String>) { runApplication<SwavesApplication>(*args) }
内容的提问来源于stack exchange,提问作者Daniel Branco
相关产品推荐
相关产品推荐

