Spring Cloud Function部署AWS Lambda遇FunctionInvoker类找不到异常
AWS Lambda部署Spring Cloud Function时出现ClassNotFoundException(找不到FunctionInvoker类)
问题描述
开发的Spring Cloud Function部署到AWS Lambda后抛出ClassNotFoundException,提示找不到org.springframework.cloud.function.adapter.aws.FunctionInvoker类,但解压部署的JAR包(oco-crds-cfd-adpater-0.0.1-SNAPSHOT-aws.jar)后,能在对应包路径下找到该类。
项目的pom.xml配置如下:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>3.2.1</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.osttra.crds</groupId> <artifactId>oco-crds-cfd-adpater</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>oco-crds-cfd-adpater</name> <description>CFD Adpater</description> <properties> <java.version>17</java.version> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <wrapper.version>1.0.29.RELEASE</wrapper.version> <aws-lambda-events.version>3.9.0</aws-lambda-events.version> <spring-cloud.version>2023.0.0</spring-cloud.version> <spring-cloud-function.version>4.1.0</spring-cloud.function.version> </properties> <dependencies> <dependency> <groupId>org.springframework.kafka</groupId> <artifactId>spring-kafka</artifactId> </dependency> <dependency> <groupId>org.springframework.retry</groupId> <artifactId>spring-retry</artifactId> <version>2.0.3</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> <version>6.0.11</version> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-function-adapter-aws</artifactId> <version>4.1.0</version> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-function-web</artifactId> <version>4.0.0</version> </dependency> <dependency> <groupId>org.modelmapper</groupId> <artifactId>modelmapper</artifactId> <version>3.1.0</version> </dependency> <dependency> <groupId>com.amazonaws</groupId> <artifactId>aws-lambda-java-events</artifactId> <version>${aws-lambda-events.version}</version> </dependency> <dependency> <groupId>software.amazon.msk</groupId> <artifactId>aws-msk-iam-auth</artifactId> <version>1.1.9</version> </dependency> <dependency> <groupId>com.amazonaws</groupId> <artifactId>aws-lambda-java-core</artifactId> <version>1.1.0</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-stream-binder-kafka</artifactId> <version>3.2.1</version> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-stream-kafka</artifactId> <version>3.2.1</version> </dependency> <dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <scope>provided</scope> </dependency> <dependency> <groupId>com.amazonaws</groupId> <artifactId>aws-java-sdk-stepfunctions</artifactId> <version>1.11.285</version> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-function-dependencies</artifactId> <version>${spring-cloud-function.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-deploy-plugin</artifactId> <configuration> <skip>true</skip> </configuration> </plugin> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <dependencies> <dependency> <groupId>org.springframework.boot.experimental</groupId> <artifactId>spring-boot-thin-layout</artifactId> <version>${wrapper.version}</version> </dependency> </dependencies> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <configuration> <createDependencyReducedPom>false</createDependencyReducedPom> <shadedArtifactAttached>true</shadedArtifactAttached> <shadedClassifierName>aws</shadedClassifierName> </configuration> </plugin> </plugins> </build> <repositories> <repository> <id>spring-snapshots</id> <name>Spring Snapshots</name> <url>https://repo.spring.io/snapshot</url> <snapshots> <enabled>true</enabled> </snapshots> </repository> <repository> <id>spring-milestones</id> <name>Spring Milestones</name> <url>https://repo.spring.io/milestone</url> <snapshots> <enabled>false</enabled> </snapshots> </repository> </repositories> <pluginRepositories> <pluginRepository> <id>spring-snapshots</id> <name>Spring Snapshots</name> <url>https://repo.spring.io/snapshot</url> <snapshots> <enabled>true</enabled> </snapshots> </pluginRepository> <pluginRepository> <id>spring-milestones</id> <name>Spring Milestones</name> <url>https://repo.spring.io/milestone</url> <snapshots> <enabled>false</enabled> </snapshots> </pluginRepository> </pluginRepositories> </project>
问题原因分析
- Thin Layout与Shade插件冲突:项目同时使用
spring-boot-thin-layout和maven-shade-plugin。Thin Layout用于生成"瘦JAR",依赖需运行时下载,但Lambda环境无法自动下载依赖,且其打包逻辑会干扰Shade插件生成的胖JAR的类加载路径。 - Spring Cloud组件版本不匹配:
spring-cloud-starter-function-web用4.0.0版本,与spring-cloud-function.version(4.1.0)不一致;spring-cloud-stream相关组件用3.2.1版本,与Spring Boot 3.2.1、Spring Cloud 2023.0.0不兼容(对应Stream版本应为4.1.x)。 - Shade插件配置不完善:缺少Spring Boot所需的资源转换器,导致打包后META-INF下的配置文件(如
spring.factories)被覆盖,类加载器无法正确找到FunctionInvoker类。
解决方案
1. 移除Spring Boot Thin Layout依赖
Lambda环境无法自动下载瘦JAR的依赖,因此不需要使用Thin Layout,修改spring-boot-maven-plugin配置:
<plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <!-- 移除thin layout相关依赖 --> </plugin>
2. 统一Spring Cloud组件版本
通过Dependency Management导入Spring Cloud Stream的依赖管理,确保所有组件版本与Spring Boot 3.2.1兼容:
<dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-function-dependencies</artifactId> <version>${spring-cloud-function.version}</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-stream-dependencies</artifactId> <version>4.1.0</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
然后更新以下依赖,去掉硬编码版本号(由Dependency Management自动管理):
<!-- 统一spring-cloud-starter-function-web版本与function版本一致 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-function-web</artifactId> <version>4.1.0</version> </dependency> <!-- 移除stream依赖的硬编码版本号 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-stream-binder-kafka</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-stream-kafka</artifactId> </dependency>
3. 完善Maven Shade插件配置
添加Spring Boot资源转换器,确保打包后的JAR能被Lambda的类加载器正确识别:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <configuration> <createDependencyReducedPom>false</createDependencyReducedPom> <shadedArtifactAttached>true</shadedArtifactAttached> <shadedClassifierName>aws</shadedClassifierName> </configuration> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> <configuration> <transformers> <!-- 合并Spring配置文件 --> <transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer"> <resource>META-INF/spring.handlers</resource> </transformer> <transformer implementation="org.springframework.boot.maven.PropertiesMergingResourceTransformer"> <resource>META-INF/spring.factories</resource> </transformer> <transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer"> <resource>META-INF/spring.schemas</resource> </transformer> <!-- 合并服务配置 --> <transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/> <!-- 指定主类为FunctionInvoker --> <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> <mainClass>org.springframework.cloud.function.adapter.aws.FunctionInvoker</mainClass> </transformer> </transformers> </configuration> </execution> </executions> </plugin>
4. 重新打包并验证
执行mvn clean package重新生成JAR包,解压后确认:
org.springframework.cloud.function.adapter.aws.FunctionInvoker类存在- META-INF下的
spring.factories文件包含FunctionInvoker的配置项
5. 确认Lambda配置
在Lambda控制台中:
- 运行时选择Java 17(与项目的
java.version一致) - 处理程序设置为
org.springframework.cloud.function.adapter.aws.FunctionInvoker
内容的提问来源于stack exchange,提问作者user2894233
相关产品推荐
相关产品推荐

