maven protobuf 编译插件使用 (2)

问题

maven protobuf 编译插件使用 (1)之后,使用maven插件编译.proto文件时,遇到如下问题

xxx.proto:12:9: "XXX" is already defined in file "xxx.proto".

插件如下

<plugin>
    <groupId>org.xolstice.maven.plugins</groupId>
    <artifactId>protobuf-maven-plugin</artifactId>
    <version>0.5.1</version>
</plugin>

原因

出现这个问题,就是因为插件指定的protoSourceRoot目录中,多个.proto文件含有相同名称message体定义。
例如,目录中存在如下student.proto后teacher.proto两个文件,都有相同的message Address。

syntax = "proto3";

option java_package = "me.fengfshao.pb";
option java_outer_classname = "TeacherProto";

message Teacher{
  string name=1;
  Address address=2;
  uint32 age=3;
}

message Address{
  string province=1;
  string street=2;
  string neighborName=3;
}
syntax = "proto3";

option java_package = "me.fengfshao.pb";
option java_outer_classname = "StudentProto";

message Student{
  string name=1;
  string address=2;
  uint32 age=3;
}

message Address{
  string province=1;
  string street=2;
}

此时使用上述插件进行proto编译时,就会出现上面的问题。

分析

为了解决这个问题,最简单的方式是可以选择使用嵌套结构,如将上述定义改为如下:

syntax = "proto3";

option java_package = "me.fengfshao.pb";
option java_outer_classname = "StudentProto";

message Student{
  string name=1;
  string address=2;
  uint32 age=3;

  message Address{
    string province=1;
    string street=2;
  }
}

对于我的场景到,如果改成嵌套结构,大量的历史pb代码需要改动,就没有这样做。
在google后,发现了这个issue,从这段话可以看出来,这个人迁到gradle之前用的maven插件不会产生这个问题
image-20220311161943624

于是尝试了插件的老版本,发现依然产生这个问题,后来在这个插件github仓库中发现它fork自另一个项目
这个maven插件经验证,支持目录中有不同的.proto文件存在同样的message定义体。

解决

maven插件替换为下面这个,由于内部实现不同,该插件即使protobuf目录中有多个protobuf文件存在同名的message定义,也不会有问题。
具体的配置如下:

<plugin>
    <groupId>com.github.igor-petruk.protobuf</groupId>
    <artifactId>protobuf-maven-plugin</artifactId>
    <version>0.6.5</version>
    <configuration>
        <!--默认是protoc,即/usr/bin/local/protoc-->
        <protocCommand>${project.basedir}/protoc</protocCommand>
        <!--inputDirectories,默认src/main/protobuf-->
        <outputDirectory>${project.basedir}/src/main/java</outputDirectory>
        <cleanOutputFolder>false</cleanOutputFolder>
    </configuration>
    <executions>
        <execution>
            <phase>process-sources</phase>
            <goals>
                <goal>run</goal>
            </goals>
        </execution>
    </executions>
</plugin>
posted @ 2022-04-18 20:54  即便那总是过去  阅读(699)  评论(0编辑  收藏  举报