It is possible to customize protoc
's output with plugins. Protoc plugins are executables that are invoked by protoc
. They read code generator requests from stdin
and output results to stdout
.
Currently, both native and pure Java plugins are supported.
Plugins written in Java (or any other JVM language) have to be resolvable as Maven artifacts. Also, the output directory for generated files is the same as the Java output directory. They are configured by adding a protocPlugins
element containing one of more protocPlugin
elements to the configuration
section.
Native plugins are supported by two dedicated goals: protobuf:compile-custom and protobuf:test-compile-custom.
protoc
pluginThe following example includes uses a single plugin to generate Java code in addition to protoc
's regular output.
<plugin> <groupId>dev.cookiecode</groupId> <artifactId>another-protobuf-maven-plugin</artifactId> <version>2.1.0</version> <extensions>true</extensions> <executions> <execution> <goals> <goal>compile</goal> </goals> <configuration> <protocPlugins> <protocPlugin> <id>myproto</id> <groupId>myproto</groupId> <artifactId>myproto-protoc-plugin</artifactId> <version>1.2</version> <mainClass>myproto.MyProtocPlugin</mainClass> </protocPlugin> </protocPlugins> </configuration> </execution> </executions> </plugin>
This will resolve the Maven artifact myproto:myproto-protoc-plugin:1.2
and its dependencies, create a plugin executable on the fly and then invoke protoc
with the argument --myproto_out=JAVAOUT
where JAVAOUT
is same directory used for the --java_out
argument.
protocPlugin
OptionsThe following options can be included in the protocPlugin
element:
id
- (required) unique id for this plugingroupId
- (required) group id for dependency resolutionartifactId
- (required) artifact id for dependency resolutionversion
- (required) version specification for dependency resolution, can be either a single version (e.g. 1.2
) or a version range (e.g. [1.2,1.3)
)classifier
- (optional) artifact classifier for dependency resolutionmainClass
- (required) Java main class to executejavaHome
- (optional) location of the JDK used for executing the plugin; uses the JDK specified in toolchains.xml
or the value of the java.home
system property as defaultwinJvmDataModel
- (optional; Windows only) data model of the JVM under javaHome
. Possible values are '32' or '64'.args
- (optional) argument to pass to the main
methodjvmArgs
- (optional) JVM argumentsThe location of the java
command (on UNIX) or jvm.dll
on Windows is determined as follows. First, the javaHome
option in protocPlugin
is used, if present. Otherwise, the jdkHome
location of the jdk
toolchain in toolchains.xml
is used. If no toolchain has been set up, the JDK that's running Maven is used (the value of the java.home
system property).
When running on Windows the plugin will try to determine whether javaHome
is pointing to a 32-bit or 64-bit JDK/JRE. If it cannot determine the data model from directories under javaHome
it will use the value of the sun.arch.data.model
system property in the JVM that is running the plugin code. If that system property does not exist it will default to 32-bit. The value can be overridden by setting the winJvmDataModel
option.
A Java-based executable is assembled on the fly from the specified artifact and its dependencies and executed by protoc
. The way this is done is platform-dependent.
On UNIX, a shell script is created in target/protoc-plugins
that builds a classpath from local repository paths of all resolved artifacts and then runs the configured java
command.
On Windows, a WinRun4J executable (bundled inside the Maven plugin jar) is copied into target/protoc-plugins
and an .ini
is generated with the required classpath, jvm.dll
location, main class and arguments.
The target/protoc-plugins
directory is prepended to the PATH
in protoc
's runtime environment.