Max A.
Max A.

Reputation: 4892

Integrate Protocol Buffers into Maven2 build

I'm experimenting with Protocol Buffers in an existing, fairly vanilla Maven 2 project. Currently, I invoke a shell script every time I need to update my generated sources. This is obviously a hassle, as I would like the sources to be generated automatically before each build. Hopefully without resorting to shameful hackery.

So, my question is two-fold:

  1. Long shot: is there a "Protocol Buffers plugin" for Maven 2 that can achieve the above in an automagic way? There's a branch on Google Code whose author appears to have taken a shot at implementing such a plugin. Unfortunately, it hasn't passed code review or been merged into protobuf trunk. The status of that plugin is thus unknown.

  2. Probably more realistic: lacking an actual plugin, how else might I go about invoking protoc from my Maven 2 build? I suppose I may be able to wire up my existing shell script into an antrun invocation or something similar.

Personal experiences are most appreciated.

Upvotes: 42

Views: 33454

Answers (9)

vr3C
vr3C

Reputation: 1774

There is a maven plugin for protobuf. https://www.xolstice.org/protobuf-maven-plugin/usage.html

The minimal config

 <plugin>
    <groupId>org.xolstice.maven.plugins</groupId>
    <artifactId>protobuf-maven-plugin</artifactId>
    <version>0.5.0</version>
    <configuration>
      <protocExecutable>/usr/local/bin/protoc</protocExecutable>
    </configuration>
    <executions>
      <execution>
        <goals>
          <goal>compile</goal>
          <goal>test-compile</goal>
        </goals>
      </execution>
    </executions>
  </plugin>

Upvotes: 4

morgwai
morgwai

Reputation: 2803

There's also great plugin by Igor Petruk named protobuf-maven-plugin. It's in central repo now and plays nicely with eclipse (m2e-1.1 is recommended).

Upvotes: 10

jsravn
jsravn

Reputation: 371

The accepted solution does not scale for multiple proto files. I had to come up with my own:

<build>
    <plugins>
        <plugin>
            <artifactId>maven-antrun-plugin</artifactId>
            <executions>
                <execution>
                    <id>compile-protoc</id>
                    <phase>generate-sources</phase>
                    <configuration>
                        <tasks>
                            <mkdir dir="${generated.sourceDirectory}" />
                            <path id="proto.path">
                                <fileset dir="src/main/proto">
                                    <include name="**/*.proto" />
                                </fileset>
                            </path>
                            <pathconvert pathsep=" " property="proto.files" refid="proto.path" />
                            <exec executable="protoc" failonerror="true">
                                <arg value="--java_out=${generated.sourceDirectory}" />
                                <arg value="-I${project.basedir}/src/main/proto" />
                                <arg line="${proto.files}" />
                            </exec>
                        </tasks>
                    </configuration>
                    <goals>
                        <goal>run</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
</build>

Upvotes: 21

Max A.
Max A.

Reputation: 4892

The accepted answer encouraged me to get the Google-provided plugin to work. I merged the branch mentioned in my question into a checkout of 2.2.0 source code, built and installed/deployed the plugin, and was able to use it in my project as follows:

  <build>
    <plugins>
      <plugin>
        <groupId>com.google.protobuf.tools</groupId>
        <artifactId>maven-protoc-plugin</artifactId>
        <version>0.0.1</version>
        <executions>
          <execution>
            <id>generate-sources</id>
            <goals>
              <goal>compile</goal>
            </goals>
            <phase>generate-sources</phase>
            <configuration>
              <protoSourceRoot>${basedir}/src/main/protobuf/</protoSourceRoot>
              <includes>
                <param>**/*.proto</param>
              </includes>
            </configuration>
          </execution>
        </executions>
        <configuration>
          <protocExecutable>/usr/local/bin/protoc</protocExecutable>
        </configuration>
      </plugin>
    </plugins>
  </build>

Note that I changed the plugin's version to 0.0.1 (no -SNAPSHOT) in order to make it go into my non-snapshot thirdparty Nexus repository. YMMV. The takeaway is that this plugin will be usable once it's no longer necessary to jump through hoops in order to get it going.

Upvotes: 23

Pascal Thivent
Pascal Thivent

Reputation: 570505

You'll find some information about the plugin available in the Protocol Buffers repository in the Protocol Buffers Compiler Maven Plug-In thread on the Protocol Buffers discussion group. My understanding is that it's usable but lacking tests. I'd give it a try.

Or you could just use the antrun plugin (snipet pasted from the thread mentioned above):

 <build>
   <plugins>
     <plugin>
       <artifactId>maven-antrun-plugin</artifactId>
       <executions>
         <execution>
           <id>generate-sources</id>
           <phase>generate-sources</phase>
           <configuration>
             <tasks>
               <mkdir dir="target/generated-sources"/>
               <exec executable="protoc">
                 <arg value="--java_out=target/generated-sources"/>
                 <arg value="src/main/protobuf/test.proto"/>
               </exec>
             </tasks>
             <sourceRoot>target/generated-sources</sourceRoot>
           </configuration>
           <goals>
             <goal>run</goal>
           </goals>
         </execution>
       </executions>
     </plugin>
   </plugins>
 </build>

 <dependencies>
   <dependency>
     <groupId>com.google.protobuf</groupId>
     <artifactId>protobuf-java</artifactId>
     <version>2.0.3</version>
   </dependency>
 </dependencies>

Upvotes: 44

Usman Ismail
Usman Ismail

Reputation: 18679

I forked of the plugin from David Trott and have it compiling multiple languages which makes it a lot more useful. See the github project here and a tutorial on integrating it with a maven build here.

Upvotes: 0

ndolgov
ndolgov

Reputation: 131

I just tried a less official but very recent (v 0.1.7) fork from https://github.com/dtrott/maven-protoc-plugin and it worked very well, courtesy of David Trott. I tested it with a couple of Maven modules one of which contained DTO-style messages and the other a service depending on them. I borrowed the plugin configuration MaxA posted on Oct 16 '09, I had protoc on my PATH and I added

<temporaryProtoFileDirectory>${basedir}/target/temp</temporaryProtoFileDirectory>

right after

<protocExecutable>protoc</protocExecutable>.

What is really nice is that all I had to do is to declare a normal dependency from the service module on the DTO module. The plugin was able to resolve proto files dependencies by finding the proto files packaged with the DTO module, extracting them to a temporary directory and using while generating code for the service. And it was smart enough not to package a second copy of the generated DTO classes with the service module.

Upvotes: 4

mrm
mrm

Reputation: 5232

I just updated the maven plugin to work with 2.2.0 -- the updated pom are attached to the code review bug.

Here are the instructions to build the plugin yourself:

svn co http://protobuf.googlecode.com/svn/branches/maven-plugin/tools/maven-plugin
cd maven-plugin
wget -O pom.xml 'http://protobuf.googlecode.com/issues/attachment?aid=8860476605163151855&name=pom.xml'
mvn install

You can then use the maven config above.

Upvotes: 4

matt b
matt b

Reputation: 139971

I think that using antrun to invoke non-Maven steps is the generally accepted solution.

You could also try the maven-exec-plugin.

Upvotes: 0

Related Questions