MAVEN automatically compiles protocol buffers

Source: Internet
Author: User
Tags requires

This article mainly solves the problem of Maven auto-compiling . proto file multi-platform Protoc: Someone in the team using a Mac someone using Windows development, compiled using the PROTOC is a binary program, There are different versions depending on the operating system. compile on Demand : There are modules (module) packages that contain the Proto directory and need to compile the. proto file. Other modules do not contain the proto directory and do not require compilation. cross-module references : Some modules need to refer to the proto directory of other modules. download Protoc to local

Defining Global Properties: keeping versions and paths consistent

<protobuf.input.directory>${project.basedir}/src/main/proto</protobuf.input.directory>
< Protobuf.output.directory>src/main/gen-java</protobuf.output.directory>
<protobuf.protoc.path >${settings.localRepository}/protoc</protobuf.protoc.path>
<protobuf.version>3.2.0</ Protobuf.version>

Reference Protobuf-api: Compiled. java files need to depend on these library files

<dependency>
    <groupId>com.google.protobuf</groupId>
    <artifactid>protobuf-java </artifactId>
    <version>${protobuf.version}</version>
</dependency>

Identify system types: differentiate Windows/linux/os X different systems, differentiate 32/64-bit, and identify results to be written into variables

<build>
    <extensions>
        <!--provides os.detected.classifier (i.e. linux-x86_64, osx-x86_64) Property-
        <extension>
            <groupId>kr.motd.maven</groupId>
            <artifactId> os-maven-plugin</artifactid>
            <version>1.4.1.Final</version>
        </extension>
    </extensions>
</build>

Automatically download Protoc to a local directory

<!--copy Protoc binary into build directory--<plugin> <groupid>org.apache.maven.plugins</grou pid> <artifactId>maven-dependency-plugin</artifactId> <version>2.10</version> <e xecutions> <execution> <id>copy-protoc</id> <phase>generate-sou
            rces</phase> <goals> <goal>copy</goal> </goals>
                        <configuration> <artifactItems> <artifactItem> <groupId>com.google.protobuf</groupId> &LT;ARTIFACTID&GT;PROTOC&LT;/ARTIFAC Tid> <version>${protobuf.version}</version> <classifier&
                        Gt;${os.detected.classifier}</classifier> <type>exe</type> <overwrite>falsE</overwrite> <outputDirectory>${protobuf.protoc.path}</outputDirectory> </artifactItem> </artifactItems> </configuration> </ Execution> </executions> </plugin>
compiling the. Proto fileUsing the IF syntax of Maven-antrun, you can determine whether a directory exists. The compilation works only if the directory exists. When invoking the Protoc file at the command line, you can include multiple-I parameters to refer to multiple paths. Here we use Maven-antrun's Propertyregex tool for string substitution. When cross-module references are required, you only need to overwrite the Protobuf.input.directory property, with semicolons spaced between multiple directories.
<propertyregex property= "Proto.include"
        input= "${protobuf.input.directory}"
        regexp= ";"
        Replace= "-i"
        defaultvalue= "${protobuf.input.directory}"
        global= "true"/>

Attention:
1. Plugin dependency: If syntax requires dependency plugin Ant-contrib:ant-contrib
2. Plugin dependency: Propertyregex tool requires reference org.apache.ant:ant-apache-regexp
3. Propertyregex does not set the property when the match fails (RegExp one does not match), so it is necessary to add DefaultValue to the source string.

In the end we write plugins like this:

<plugin> <artifactId>maven-antrun-plugin</artifactId> <dependencies> <dependenc
            Y> <groupId>ant-contrib</groupId> <artifactId>ant-contrib</artifactId>
                    <version>1.0b3</version> <exclusions> <exclusion>
                <groupId>ant</groupId> <artifactId>ant</artifactId> </exclusion> </exclusions> </dependency> <dependency> &L
            T;groupid>org.apache.ant</groupid> <artifactId>ant-apache-regexp</artifactId> <version>1.8.2</version> </dependency> <dependency> <groupid>or G.apache.ant</groupid> <artifactId>ant-nodeps</artifactId> <version>1.8.1&
        Lt;/version></dependency> </dependencies> <executions> <execution> <id>compi
                Le-protoc</id> <phase>generate-sources</phase> <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> &l T;property name= "Protoc.filename" value= "protoc-${protobuf.version}-${os.detected.cl
                                      Assifier}.exe "/> <property name=" Protoc.filepath " Value= "${protobuf.protoc.path}/${protoc.filename}"/> <propertyregex property= "Proto.incl
                   Ude                        input= "${protobuf.input.directory}" regexp= ";" Replace= "-i" defaultvalue= "${protobuf.inpu T.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.P
                                Ath "/> <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>run</goal> </goals> </execution> </executions> </plugin&gt ;
Add to Source

Add the newly generated Gen-java directory to the project's source collection and participate in the compilation.

<!--add generated proto buffer classes into the package--
<plugin>
    <groupId> org.codehaus.mojo</groupid>
    <artifactId>build-helper-maven-plugin</artifactId>
    < version>1.7</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>
Resolving protobuf-api Version Conflicts

There are times when we encounter protobuf version conflicts.
For example, our project uses the protobuf3.2 version, and some of the libraries referenced to the PROTOBUF version 2.5. Two versions of some API conflicts can cause unexpected problems. We can use the shade plugin to replace the PROTOBUF-API with the private package name to avoid naming conflicts.

<!--  Shade protobuf To avoid version conflicts--
<plugin>
    <groupId> org.apache.maven.plugins</groupid>
    <artifactId>maven-shade-plugin</artifactId>
    < version>2.4.2</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>

In the project, you need to put

Import com.google.protobuf.*;

Replaced by

Import groupid.artifactid.shaded.protobuf.*;

Reference: Compiling Protocol buffers Sources in Maven

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.