foshan
foshan

Reputation: 31

protoc-jar-maven-plugin and protoc import path

I am currently working on an application composed of multiple Java services that should communicate using gRPC. The team decided to organize all .proto file in a central shared repository dedicated to that purpose.

The repository is structured as bellow :

.
├── service-a
│   └── v1
|       |── pom.xml
│       └── a.proto
├── service-b
│   └── v1
|       |── pom.xml
│       └── b.proto

To handle the code generation, we wrote a small bash script that loop over all services in the shared repository and generates, for each major version, a pom.xml containing a plugin to generate the Java classes and package them in a JAR with all required dependencies (i.e. protobuf-java, grpc-protobuf, grpc-stub).

A service's .proto files might reference messages from other services using imports. Yet I cannot figure a way to configure the `protoc-jar-maven-plugin` to tell protoc to set the import path to the shared repository's root so it can resolve the imports defined in each service's .proto files (all the import path in proto files are relative to the repository's root).

Bellow is an example of a .proto file importing another file and the configuration of the `protoc-jar-maven-plugin` inside the pom.xml generated for each service's major version directory:

syntax = "proto3";

package b.v1;

// Import statement allowing to use the "a.v1.A" message
// Path is relative to the shared repository's root
import "service-a/v1/a.proto";

service B {
  rpc someRpc(a.v1.A) returns (a.v1.A);
}
<plugin>
    <groupId>com.github.os72</groupId>
    <artifactId>protoc-jar-maven-plugin</artifactId>
    <version>3.11.4</version>
    <executions>
        <execution>
            <phase>generate-sources</phase>
            <goals>
                <goal>run</goal>
            </goals>
            <configuration>
                <includeMavenTypes>direct</includeMavenTypes>
                                <!-- Including all .proto file in the shared repo. so -->
                                <!-- that imports can be resolved -->
                <includeDirectories>
                    <include>../../</include>
                </includeDirectories>
                                <!-- Path to the service's .proto files -->
                <inputDirectories>
                    <include>./</include>
                </inputDirectories>
            </configuration>
        </execution>
    </executions>
</plugin>

When I try to generate the sources of a service that uses another service's messages, the plugin fails telling me that protoc exited with an error due to not finding the import defined in the service's proto file.

I should also specify that this POM sits at the same level as the .proto files for each major API version and is executed using mvn clean install so that the generated sources are installed on the local Maven repository for further local use.

So my question is, how can the plugin be configured to set protoc import path to the repository's root so that each .proto file imports are resolved ?

I tried tuning the includeDirectories and inputDirectories as specified in the documentation but without much success.

Upvotes: 1

Views: 1951

Answers (1)

Radoslav Ivanov
Radoslav Ivanov

Reputation: 1072

Can you try with that config which is similar to yours (except include directories) and works fine here?

                <plugin>
                    <groupId>com.github.os72</groupId>
                    <artifactId>protoc-jar-maven-plugin</artifactId>
                    <version>3.11.4</version>
                    <executions>
                        <execution>
                            <phase>generate-sources</phase>
                            <goals>
                                <goal>run</goal>
                            </goals>
                            <configuration>
                                <protocVersion>3.11.4</protocVersion>
                                <includeDirectories>
                                    <include>src/main/resources</include>
                                </includeDirectories>
                                <inputDirectories>
                                    <include>src/main/resources</include>
                                </inputDirectories>
                               <includeMavenTypes>direct</includeMavenTypes>
                            </configuration>
                        </execution>
                    </executions>
                </plugin>

Upvotes: 1

Related Questions