本文主要解决maven自动编译.proto文件的问题
定义全局属性:保持版本和路径一致
<protobuf.input.directory>${project.basedir}/src/main/protoprotobuf.input.directory>
<protobuf.output.directory>src/main/gen-javaprotobuf.output.directory>
<protobuf.protoc.path>${settings.localRepository}/protocprotobuf.protoc.path>
<protobuf.version>3.2.0protobuf.version>
引用protobuf-API:编译成的.java文件需要依赖这些库文件
<dependency>
<groupId>com.google.protobufgroupId>
<artifactId>protobuf-javaartifactId>
<version>${protobuf.version}version>
dependency>
识别系统类型:区分Windows/Linux/OS X 不同系统,区分32/64-bit,识别结果会写入到变量里面
<build>
<extensions>
<extension>
<groupId>kr.motd.mavengroupId>
<artifactId>os-maven-pluginartifactId>
<version>1.4.1.Finalversion>
extension>
extensions>
build>
自动下载protoc到本地目录
<plugin>
<groupId>org.apache.maven.pluginsgroupId>
<artifactId>maven-dependency-pluginartifactId>
<version>2.10version>
<executions>
<execution>
<id>copy-protocid>
<phase>generate-sourcesphase>
<goals>
<goal>copygoal>
goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>com.google.protobufgroupId>
<artifactId>protocartifactId>
<version>${protobuf.version}version>
<classifier>${os.detected.classifier}classifier>
<type>exetype>
<overWrite>falseoverWrite>
<outputDirectory>${protobuf.protoc.path}outputDirectory>
artifactItem>
artifactItems>
configuration>
execution>
executions>
plugin>
<propertyregex property="proto.include"
input="${protobuf.input.directory}"
regexp=";"
replace=" -I"
defaultvalue="${protobuf.input.directory}"
global="true" />
注意:
1. 插件依赖: if语法需要依赖插件ant-contrib:ant-contrib
2. 插件依赖: propertyregex工具需要引用 org.apache.ant:ant-apache-regexp
3. propertyregex 在匹配失败(regexp一个都没有匹配到)的时候,不会设置property;因此需要加入defaultvalue 设置成源串。
最后我们写成插件就是这样子:
<plugin>
<artifactId>maven-antrun-pluginartifactId>
<dependencies>
<dependency>
<groupId>ant-contribgroupId>
<artifactId>ant-contribartifactId>
<version>1.0b3version>
<exclusions>
<exclusion>
<groupId>antgroupId>
<artifactId>antartifactId>
exclusion>
exclusions>
dependency>
<dependency>
<groupId>org.apache.antgroupId>
<artifactId>ant-apache-regexpartifactId>
<version>1.8.2version>
dependency>
<dependency>
<groupId>org.apache.antgroupId>
<artifactId>ant-nodepsartifactId>
<version>1.8.1version>
dependency>
dependencies>
<executions>
<execution>
<id>compile-protocid>
<phase>generate-sourcesphase>
<configuration>
<tasks>
<taskdef resource="net/sf/antcontrib/antcontrib.properties"/>
<available property="isExist" file="src/main/proto" type="dir"/>
<if>
<equals arg1="${isExist}" arg2="true"/>
<then>
<property name="protoc.filename"
value="protoc-${protobuf.version}-${os.detected.classifier}.exe"/>
<property name="protoc.filepath"
value="${protobuf.protoc.path}/${protoc.filename}"/>
<propertyregex property="proto.include"
input="${protobuf.input.directory}"
regexp=";"
replace=" -I"
defaultvalue="${protobuf.input.directory}"
global="true" />
<chmod file="${protoc.filepath}" perm="ugo+rx"/>
<path id="proto.path">
<fileset dir="src/main/proto">
<include name="**/*.proto"/>
fileset>
path>
<mkdir dir="src/main/gen-java"/>
<pathconvert pathsep=" " property="proto.files" refid="proto.path"/>
<exec executable="${protoc.filepath}" failonerror="true">
<arg value="--java_out=${protobuf.output.directory}"/>
<arg value="-I${proto.include}"/>
<arg line="${proto.files}"/>
exec>
then>
if>
tasks>
<sourceRoot>${protobuf.output.directory}sourceRoot>
configuration>
<goals>
<goal>rungoal>
goals>
execution>
executions>
plugin>
把新生成的gen-java目录加入到项目的source集合中,一起参与编译。
<plugin>
<groupId>org.codehaus.mojogroupId>
<artifactId>build-helper-maven-pluginartifactId>
<version>1.7version>
<executions>
<execution>
<id>add-classesid>
<phase>generate-sourcesphase>
<goals>
<goal>add-sourcegoal>
goals>
<configuration>
<sources>
<source>${protobuf.output.directory}source>
sources>
configuration>
execution>
executions>
plugin>
有的时候,我们会遇到protobuf版本冲突。
比如,我们的工程用到protobuf3.2版本,而引用到的一些库用到了protobuf 2.5版本。两个版本的一些api冲突,可能造成意想不到的问题。我们可以利用shade插件,把protobuf-API全部替换成私有的包名,避免命名冲突。
<plugin>
<groupId>org.apache.maven.pluginsgroupId>
<artifactId>maven-shade-pluginartifactId>
<version>2.4.2version>
<executions>
<execution>
<phase>packagephase>
<goals>
<goal>shadegoal>
goals>
<configuration>
<relocations>
<relocation>
<pattern>com.google.protobufpattern>
<shadedPattern>${project.groupId}.${project.artifactId}.shaded.protobufshadedPattern>
relocation>
relocations>
configuration>
execution>
executions>
plugin>
在项目中,需要把
import com.google.protobuf.*;
替换成
import groupId.artifactId.shaded.protobuf.*;
参考:Compiling Protocol Buffers Sources in Maven