启动gRPC Spring Boot客户端时出现EmbeddedTomcat Bean创建错误
问题现象
启动Spring Boot gRPC客户端应用时抛出异常,错误触发节点为GrpcClientBeanPostProcessor处理阶段,核心报错日志如下:
org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext WARN 上下文初始化过程中遇到异常,已取消刷新尝试:org.springframework.context.ApplicationContextException: 无法启动嵌入式容器;嵌套异常为org.springframework.beans.factory.BeanCreationException: 创建名为'org.springframework.boot.autoconfigure.web.EmbeddedServletContainerAutoConfiguration$EmbeddedTomcat'的Bean时出错:Bean初始化失败;嵌套异常为java.lang.AbstractMethodError
环境依赖配置
当前项目核心依赖版本配置如下:
<java.version>1.8</java.version> <grpc.version>1.47.0</grpc.version> <protoc.version>3.5.1</protoc.version> <protobuf-maven-plugin.version>0.6.1</protobuf-maven-plugin.version> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.3.6.RELEASE</version> </parent> <dependencies> <dependency> <groupId>net.devh</groupId> <artifactId>grpc-client-spring-boot-starter</artifactId> <version>2.9.0.RELEASE</version> </dependency> <dependency> <groupId>io.grpc</groupId> <artifactId>grpc-protobuf</artifactId> <version>${grpc.version}</version> </dependency> <dependency> <groupId>io.grpc</groupId> <artifactId>grpc-stub</artifactId> <version>${grpc.version}</version> </dependency> <dependency> <groupId>com.google.protobuf</groupId> <artifactId>protobuf-java-util</artifactId> <version>3.12.2</version> </dependency> </dependencies>
问题根因
该报错本质是多组依赖版本严重不兼容导致的:
- Spring Boot与gRPC starter版本完全不匹配:当前使用的Spring Boot 1.3.6.RELEASE是2016年发布的1.x版本,而引入的
grpc-client-spring-boot-starter 2.9.0.RELEASE仅适配Spring Boot 2.x版本,两者的Bean生命周期扩展、自动配置逻辑存在大量API差异,GrpcClientBeanPostProcessor实现了Spring 2.x版本才有的后置处理器接口方法,在1.x版本的Spring容器中调用时就会抛出AbstractMethodError。 - Protobuf版本混乱冲突:grpc 1.47.0本身内置依赖的Protobuf版本为3.19.2,但是项目中手动指定的protoc编译版本为3.5.1、protobuf-java-util版本为3.12.2,编译生成的Protobuf代码、运行时Protobuf工具类、gRPC依赖的Protobuf内核三者版本不一致,类方法签名不匹配也会触发抽象方法错误。
排查解决步骤
- 优先对齐Spring Boot与gRPC starter的版本适配关系:如果必须保留Spring Boot 1.3.6.RELEASE版本,需要将
grpc-client-spring-boot-starter降级到适配Spring Boot 1.x的最高版本1.4.2.RELEASE,同时将grpc相关依赖版本降到1.23.x区间,和starter的依赖要求对齐。更推荐的方案是将Spring Boot升级到2.7.x版本,完全适配2.9.0.RELEASE版本的gRPC starter,从根源解决Spring内核API不兼容问题。 - 统一全链路Protobuf版本:对齐protoc编译版本、protobuf-java版本、protobuf-java-util版本、grpc内置的Protobuf版本,比如使用grpc 1.47.0时,所有Protobuf相关依赖统一使用3.19.2版本,同时将protobuf-maven-plugin升级到和Protobuf版本匹配的版本,保证编译生成的代码和运行时依赖的类方法签名完全一致。
- 排查传递依赖冲突:执行Maven命令
mvn dependency:tree -Dincludes=com.google.protobuf:*查看所有引入的Protobuf依赖,通过exclusion标签排除掉非预期版本的传递依赖,确保运行时Classpath下仅存在一个统一版本的Protobuf相关包。 - 纯gRPC客户端场景可跳过Web容器初始化:如果项目不需要提供HTTP接口、仅作为gRPC客户端运行,可以在启动类的
@SpringBootApplication注解上添加排除参数exclude = {EmbeddedServletContainerAutoConfiguration.class},跳过嵌入式Tomcat的初始化流程,避免无关Bean加载触发不兼容报错。
内容的提问来源于stack exchange,提问作者Jithesh Nair
相关产品推荐
相关产品推荐

