通过maven自动化构建protocal buffer
当对代码进行工程构建的时候,如果能够尽可能的自动化,这样对于提升整个软件质量、节省人力成本、减少因为人工干预导致的各种不可预知的错误是很好。
从protobuf的官方文档来看,通过cmd调用protoc当然可以生成相应的代码,但是对构建不够友好。于是,可以考虑通过maven来进行自动化构建,在启动maven构建的时候,自动调用protoc,生成代码,并打包成相应的jar包,集成到工程发布包中。
这里有2种方式,如下。
第1种方式:使用protobuf-maven-plugin
配置插件protobuf-maven-plugin
先从官网[2]上将protobuf的工具包下载下来,然后拷贝到工程目录下,配置POM文件如下, 通过相对路径引用protoc.exe文件。
.protow文件默认的路径在src/main/proto文件中。下面所有的子目录都会被当成包结构。
protobuf-maven-plugin[1]的maven配置如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> </plugin> <plugin> <groupId>org.xolstice.maven.plugins</groupId> <artifactId>protobuf-maven-plugin</artifactId> <configuration> <checkStaleness>false</checkStaleness> <staleMillis>10000</staleMillis> <protocExecutable>${basedir}\..\protobuf\bin\protoc.exe</protocExecutable> <useArgumentFile>true</useArgumentFile> </configuration> <executions> <execution> <goals> <goal>compile</goal> <goal>test-compile</goal> </goals> </execution> </executions> </plugin> </plugins> </build>
|
进一步改进maven配置
如果我们的POM构建需要同时支持不同的平台,比如windows,MAC,Linux,但是这些平台上的protoc路径和文件都不一样,怎么办呢? 可以考虑如下方式。
通过profiles[3]的<activation>如果通过profiles来激活不同的脚本调用:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| <profiles> <profile> <id>windows</id> <activation> <os> <family>Windows</family> <arch>x86</arch> </os> </activation> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> </plugin> <plugin> <groupId>org.xolstice.maven.plugins</groupId> <artifactId>protobuf-maven-plugin</artifactId> <configuration> <checkStaleness>false</checkStaleness> <staleMillis>10000</staleMillis> <protocExecutable>${basedir}\..\protobuf\bin\protoc.exe</protocExecutable> <useArgumentFile>true</useArgumentFile> </configuration> <executions> <execution> <goals> <goal>compile</goal> <goal>test-compile</goal> </goals> </execution> </executions> </plugin> </plugins> </build> </profile> </profiles>
|
第2种方式通过antrun插件来完成
通过组合os-maven-plugin, maven-antrun-plugin,build-helper-maven-plugin等多个插件来完成,效果是完全一样的。
这个例子[4]的价值在于maven的灵活性和可定制型,对于理解如何使用maven来达到比较复杂的目的很有帮助。特别是antrun插件,很多遗留的工程在满足条件的情况下可以往maven进行迁移。
参考文档:
前置条件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| <properties>
<protobuf.input.directory>${project.basedir}/src/main/proto</protobuf.input.directory> <protobuf.output.directory>${project.build.directory}/generated-sources</protobuf.output.directory>
<build-helper-maven-plugin.version>1.9.1</build-helper-maven-plugin.version> <maven-antrun-plugin.version>1.8</maven-antrun-plugin.version> <maven-dependency-plugin.version>2.10</maven-dependency-plugin.version> <maven-shade-plugin.version>2.4.2</maven-shade-plugin.version> <os-maven-plugin.version>1.4.1.Final</os-maven-plugin.version> <protobuf.version>3.0.0-beta-1</protobuf.version>
</properties>
|
配置依赖的Protocol Buffer API
1 2 3 4 5
| <dependency> <groupId>com.google.protobuf</groupId> <artifactId>protobuf-java</artifactId> <version>${protobuf.version}</version> </dependency>
|
检查操作系统类型,并生成相应的工程属性Properties
1 2 3 4 5 6 7 8 9 10 11 12
| <build> <extensions> <extension> <groupId>kr.motd.maven</groupId> <artifactId>os-maven-plugin</artifactId> <version>${os-maven-plugin.version}</version> </extension> </extensions>
</build>
|
自动下载平台相关的编译器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-dependency-plugin</artifactId> <version>${maven-dependency-plugin.version}</version> <executions> <execution> <id>copy-protoc</id> <phase>generate-sources</phase> <goals> <goal>copy</goal> </goals> <configuration> <artifactItems> <artifactItem> <groupId>com.google.protobuf</groupId> <artifactId>protoc</artifactId> <version>${protobuf.version}</version> <classifier>${os.detected.classifier}</classifier> <type>exe</type> <overWrite>true</overWrite> <outputDirectory>${project.build.directory}</outputDirectory> </artifactItem> </artifactItems> </configuration> </execution> </executions> </plugin>
|
调用protoc生成相关的Java代码。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-antrun-plugin</artifactId> <version>${maven-antrun-plugin.version}</version> <executions> <execution> <id>exec-protoc</id> <phase>generate-sources</phase> <configuration> <target> <property name="protoc.filename" value="protoc-${protobuf.version}-${os.detected.classifier}.exe"/> <property name="protoc.filepath" value="${project.build.directory}/${protoc.filename}"/> <chmod file="${protoc.filepath}" perm="ugo+rx"/> <mkdir dir="${protobuf.output.directory}" /> <path id="protobuf.input.filepaths.path"> <fileset dir="${protobuf.input.directory}"> <include name="**/*.proto"/> </fileset> </path> <pathconvert pathsep=" " property="protobuf.input.filepaths" refid="protobuf.input.filepaths.path"/> <exec executable="${protoc.filepath}" failonerror="true"> <arg value="-I"/> <arg value="${protobuf.input.directory}"/> <arg value="--java_out"/> <arg value="${protobuf.output.directory}"/> <arg line="${protobuf.input.filepaths}"/> </exec> </target> </configuration> <goals> <goal>run</goal> </goals> </execution> </executions> </plugin>
|
将Java代码添加到包中
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>build-helper-maven-plugin</artifactId> <version>${build-helper-maven-plugin.version}</version> <executions> <execution> <id>add-classes</id> <phase>generate-sources</phase> <goals> <goal>add-source</goal> </goals> <configuration> <sources> <source>${protobuf.output.directory}</source> </sources> </configuration> </execution> </executions> </plugin>
|
对Protocol Buffer包进行shading
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>${maven-shade-plugin.version}</version> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> <configuration> <relocations> <relocation> <pattern>com.google.protobuf</pattern> <shadedPattern>${project.groupId}.${project.artifactId}.shaded.protobuf</shadedPattern> </relocation> </relocations> </configuration> </execution> </executions> </plugin>
|