使用ProtobufUtil将JSON转换为Protobuf时遭遇异常问题
JSON转Protobuf在应用中抛出NoSuchMethodError(main方法正常)
我尝试使用Protobuf工具将JSON转换为Protobuf,在main方法中运行时完全正常,但在应用程序中使用时出现如下异常:
Caused by: java.lang.NoSuchMethodError: com.google.protobuf.Descriptors$FileDescriptor.internalBuildGeneratedFileFrom([Ljava/lang/String;[Lcom/google/protobuf/Descriptors$FileDescriptor;)Lcom/google/protobuf/Descriptors$FileDescriptor; at com.google.protobuf.AnyProto.<clinit>(AnyProto.java:39) at com.google.protobuf.Any.getDescriptor(Any.java:32) at com.google.protobuf.util.JsonFormat$ParserImpl.buildWellKnownTypeParsers(JsonFormat.java:1361) at com.google.protobuf.util.JsonFormat$ParserImpl.<clinit>(JsonFormat.java:1355) at com.google.protobuf.util.JsonFormat$Parser.merge(JsonFormat.java:471) at com.opentable.extension.ProtobufUtil.fromJson(ProtobufUtil.java:13)
问题原因
这个错误的核心是Protobuf依赖版本冲突:
- 单独运行main方法时,类路径仅包含符合预期的Protobuf新版本(该版本包含
internalBuildGeneratedFileFrom方法); - 但在应用程序环境中,存在多个不同版本的Protobuf jar包,类加载器优先加载了不包含该方法的旧版本Protobuf类,导致调用时触发方法找不到的错误。
internalBuildGeneratedFileFrom是Protobuf新版本中新增的方法,旧版本(如3.0.x及更早)没有该方法,而AnyProto类初始化时必须调用此方法,因此抛出异常。
解决方案
1. 统一Protobuf依赖版本
- 使用依赖分析工具排查:
- Maven项目执行
mvn dependency:tree,Gradle项目执行./gradlew dependencies,找出所有直接/间接引入的Protobuf相关依赖; - 排除所有旧版本的Protobuf依赖,确保项目全局只使用一个兼容的新版本(推荐3.19.0及以上);
- 用Maven的
<dependencyManagement>或Gradle的platform插件统一声明Protobuf版本,强制所有依赖遵循该版本。
- Maven项目执行
2. 清理应用容器类路径
如果是Web容器(如Tomcat)或分布式框架环境,检查容器的lib目录、共享类路径中是否存在多余的Protobuf jar包,移除旧版本文件。
3. 对齐编译器与运行时版本
确保生成Protobuf Java类所用的protoc编译器版本,与项目依赖的Protobuf Java运行时版本完全一致,避免生成的类依赖运行时不存在的方法。
内容的提问来源于stack exchange,提问作者user2640248
相关产品推荐
相关产品推荐

