protobuf新增message报错:类型已存在

时间:2021-04-20 15:01:32

  问题现象:在一个已有的proto文件(RecommendResponse.proto)中新增一个message(BookList),用maven编译proto文件时报错:

E:\workspace\ms-selection-service\ms-selection-api>mvn clean install
[INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------------
[INFO] Detecting the operating system and CPU architecture
[INFO] ------------------------------------------------------------------------
[INFO] os.detected.name: windows
[INFO] os.detected.arch: x86_64
[INFO] os.detected.version: 10.0
[INFO] os.detected.version.major:
[INFO] os.detected.version.minor:
[INFO] os.detected.classifier: windows-x86_64
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building ms-selection-api 1.0.
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ ms-selection-api ---
[INFO] Deleting E:\workspace\ms-selection-service\ms-selection-api\target
[INFO]
[INFO] --- protobuf-maven-plugin:0.5.:compile (default) @ ms-selection-api ---
[INFO] Compiling proto file(s) to E:\workspace\ms-selection-service\ms-selection-api\target\generated-sources\protobuf\java
[ERROR] PROTOC FAILED: recommend/RecommendResponse.proto::: "BookList.bookName" is already defined in file "contentrecommend/ContentRecommendResponse.proto".
recommend/RecommendResponse.proto::: "BookList.authorName" is already defined in file "contentrecommend/ContentRecommendResponse.proto".
recommend/RecommendResponse.proto::: "BookList.bookCover" is already defined in file "contentrecommend/ContentRecommendResponse.proto".
recommend/RecommendResponse.proto::: "BookList.bookUrl" is already defined in file "contentrecommend/ContentRecommendResponse.proto".
recommend/RecommendResponse.proto::: "BookList.coPercent" is already defined in file "contentrecommend/ContentRecommendResponse.proto".
recommend/RecommendResponse.proto::: "BookList.contentType" is already defined in file "contentrecommend/ContentRecommendResponse.proto".
recommend/RecommendResponse.proto::: "BookList" is already defined in file "contentrecommend/ContentRecommendResponse.proto".
recommend/RecommendResponse.proto::: "BookList" seems to be defined in "contentrecommend/ContentRecommendResponse.proto", which is not imported by "recommend/RecommendResponse.proto". To use it here, please add the necessary import.

  先看下RecommendResponse.proto:

syntax = "proto3";

option java_package = "cn.wlf.selection.proto.base";

message RecommendResponse {

     string pluginCode=;
string status=;
string isvisable=;
string isShowLine=;
Recommend data=;
string messageDesc=;
repeated BookList bookList= ; } message Recommend{ repeated RecommendData buttons=;
map<string, string> ctag = ;
string isMarginTop=;
string isMarginBottom=; } message RecommendData{ string name=; string url=;
} message BookList{
string bookName=;
string authorName=;
string bookCover=;
string bookUrl=;
string coPercent=;
string contentType=; }

  再看ContentRecommendResponse.proto:

syntax = "proto3";

option java_package = "cn.wlf.selection.proto.base";

message  ContentRecommendResponse {
string pluginCode=; string status=; string isvisable=; string messageDesc=; ContentRecommendData data=; }
message ContentRecommendData{ string isMarginTop = ; string isMarginBottom = ; string isPaddingTop = ; string isShowLine = ; string dataFrom = ; string title = ; string style = ; repeated BookList bookList=; BiData biData = ; }
message BookList{
string bookName=;
string authorName=;
string bookCover=;
string bookUrl=;
string coPercent=;
string contentType=;
} message BiData{ string msisdn = ;
string bid = ;
string pageNo = ;
string showNum = ;
string clientVersion = ;
string instanceId = ;
}

  问题定位:从报错信息中其实已经告诉我们,在ContentRecommendResponse.proto已经存在BookList这个message了,从上面也能看到两个proto存在同名message。

  问题解决:

  1、如果新增的BookList跟已有的数据结构一样,那么只需要引入即可,RecommendResponse.proto改为:

syntax = "proto3";

option java_package = "cn.wlf.selection.proto.base";
import "contentrecommend/ContentRecommendResponse.proto"; message RecommendResponse { string pluginCode=;
string status=;
string isvisable=;
string isShowLine=;
Recommend data=;
string messageDesc=;
repeated BookList bookList= ; } message Recommend{ repeated RecommendData buttons=;
map<string, string> ctag = ;
string isMarginTop=;
string isMarginBottom=; } message RecommendData{ string name=; string url=;
}

  2、如果BookList数据结构改了,那么就没法复用了,只能改类名,RecommendResponse.proto改为:

syntax = "proto3";

option java_package = "cn.wlf.selection.proto.base";

message RecommendResponse {

     string pluginCode=;
string status=;
string isvisable=;
string isShowLine=;
Recommend data=;
string messageDesc=;
repeated BookListNew bookList= ; } message Recommend{ repeated RecommendData buttons=;
map<string, string> ctag = ;
string isMarginTop=;
string isMarginBottom=; } message RecommendData{ string name=; string url=;
} message BookListNew{
string bookCover=;
}

  虽然类名从BookList改为BookListNew,但实例名没改,还是bookList,最终输出的响应字段名还是叫bookList的。

  以上两种情况修改后跑maven均可成功编译出java文件。