This is an automated email from the ASF dual-hosted git repository.

He-Pin pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/pekko-grpc.git


The following commit(s) were added to refs/heads/main by this push:
     new fac9b2ba fix: pass all protoPaths as -I import params to protoc in 
Maven plugin (#773)
fac9b2ba is described below

commit fac9b2bad9f8a9d7b0f0539272ad57a3d055b7b6
Author: He-Pin(kerr) <[email protected]>
AuthorDate: Fri Jul 3 11:12:14 2026 +0800

    fix: pass all protoPaths as -I import params to protoc in Maven plugin 
(#773)
    
    Motivation:
    When using Maven, only the current protoDir was passed as -I to protoc.
    This prevented proto files from importing definitions in other configured
    protoPaths (e.g. unpacked artifact dependencies). sbt and Gradle already
    supported this use case.
    
    Modification:
    Extract normalize helper and normalizedProtoPaths lazy val. Remove
    protoDir parameter from executeProtoc and instead pass all
    normalizedProtoPaths as -I include paths. Update Maven docs to document
    the artifact dependency workflow.
    
    Result:
    All configured protoPaths are now passed as -I to protoc, enabling proto
    imports from artifact dependencies in Maven builds.
    
    Tests:
    sbt "maven-plugin / compile" — success
    
    References:
    Fixes akka/akka-grpc#1300, Fixes akka/akka-grpc#686, Refs 
akka/akka-grpc#1768
---
 docs/src/main/paradox/buildtools/maven.md          | 51 ++++++++++++++++++++--
 .../pekko/grpc/maven/AbstractGenerateMojo.scala    | 37 +++++++++-------
 2 files changed, 69 insertions(+), 19 deletions(-)

diff --git a/docs/src/main/paradox/buildtools/maven.md 
b/docs/src/main/paradox/buildtools/maven.md
index 01b66304..7d9354c2 100644
--- a/docs/src/main/paradox/buildtools/maven.md
+++ b/docs/src/main/paradox/buildtools/maven.md
@@ -77,10 +77,53 @@ which is a relative path to the project basedir. The below 
configuration overrid
 In gRPC it is common to make the version of the protocol you are supporting
 explicit by duplicating the proto definitions in your project.
 
-When using @ref[sbt](sbt.md) as a build system, we also support loading your
-proto definitions from a dependency classpath. This is not yet supported
-for Maven and @ref[Gradle](gradle.md). If you are interested in this feature
-it is tracked in issue [#152](https://github.com/akka/akka-grpc/issues/152).
+When using @ref[sbt](sbt.md) or @ref[Gradle](gradle.md) as a build system, we 
also support loading your
+proto definitions from a dependency classpath.
+
+For Maven, you can achieve a similar result by using the 
`maven-dependency-plugin` to unpack the
+proto files from a dependency and then adding the unpacked directory as a 
`protoPath`:
+
+`pom.xml`
+:   ```xml
+    <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-dependency-plugin</artifactId>
+        <executions>
+            <execution>
+                <id>unpack-proto</id>
+                <phase>generate-sources</phase>
+                <goals>
+                    <goal>unpack</goal>
+                </goals>
+                <configuration>
+                    <artifactItems>
+                        <artifactItem>
+                            <groupId>com.example</groupId>
+                            <artifactId>my-protos</artifactId>
+                            <version>1.0.0</version>
+                            <type>jar</type>
+                            
<outputDirectory>${project.build.directory}/protos-dep</outputDirectory>
+                        </artifactItem>
+                    </artifactItems>
+                </configuration>
+            </execution>
+        </executions>
+    </plugin>
+    <plugin>
+        <groupId>org.apache.pekko</groupId>
+        <artifactId>pekko-grpc-maven-plugin</artifactId>
+        <version>${pekko.grpc.version}</version>
+        <configuration>
+            <protoPaths>
+                <protoPath>src/main/protobuf</protoPath>
+                <protoPath>${project.build.directory}/protos-dep</protoPath>
+            </protoPaths>
+        </configuration>
+    </plugin>
+    ```
+
+All configured `protoPaths` are passed as `-I` import parameters to `protoc`, 
allowing proto files
+in your project to import definitions from the unpacked artifact.
 
 ## JDK 8 support
 
diff --git 
a/maven-plugin/src/main/scala/org/apache/pekko/grpc/maven/AbstractGenerateMojo.scala
 
b/maven-plugin/src/main/scala/org/apache/pekko/grpc/maven/AbstractGenerateMojo.scala
index 5f8bedb7..ea7c0a06 100644
--- 
a/maven-plugin/src/main/scala/org/apache/pekko/grpc/maven/AbstractGenerateMojo.scala
+++ 
b/maven-plugin/src/main/scala/org/apache/pekko/grpc/maven/AbstractGenerateMojo.scala
@@ -129,21 +129,27 @@ abstract class AbstractGenerateMojo @Inject() 
(buildContext: BuildContext) exten
 
   def addGeneratedSourceRoot(generatedSourcesDir: String): Unit
 
+  // 
https://maven.apache.org/plugin-developers/common-bugs.html#Resolving_Relative_Paths
+  def normalize(protoPath: String): File = {
+    val protoFile = new File(protoPath)
+    if (!protoFile.isAbsolute()) {
+      new File(project.getBasedir(), protoPath).toPath().normalize().toFile()
+    } else {
+      protoFile
+    }
+  }
+
+  lazy val normalizedProtoPaths: Seq[File] = {
+    import scala.jdk.CollectionConverters._
+    protoPaths.asScala.map(normalize).toSeq
+  }
+
   override def execute(): Unit = {
     val chosenLanguage = parseLanguage(language)
 
     var directoryFound = false
-    protoPaths.forEach { protoPath =>
-      // verify proto dir exists
-      // 
https://maven.apache.org/plugin-developers/common-bugs.html#Resolving_Relative_Paths
-      val protoDir = {
-        val protoFile = new File(protoPath)
-        if (!protoFile.isAbsolute()) {
-          new File(project.getBasedir(), 
protoPath).toPath().normalize().toFile()
-        } else {
-          protoFile
-        }
-      }
+
+    normalizedProtoPaths.foreach { protoDir =>
       if (protoDir.exists()) {
         directoryFound = true
         // generated sources should be compiled
@@ -218,15 +224,16 @@ abstract class AbstractGenerateMojo @Inject() 
(buildContext: BuildContext) exten
   private[this] def executeProtoc(
       protocCommand: Seq[String] => Int,
       schemas: Set[File],
-      protoDir: File,
       protocOptions: Seq[String],
       targets: Seq[Target]): Int =
     try {
-      val incPath = "-I" + protoDir.getCanonicalPath
+      val protocIncludePaths = normalizedProtoPaths.map { includePath =>
+        "-I" + includePath.getCanonicalPath
+      }
       protocbridge.ProtocBridge.execute(
         ProtocRunner.fromFunction((args, _) => protocCommand(args)),
         targets,
-        Seq(incPath) ++ protocOptions ++ schemas.map(_.getCanonicalPath),
+        protocIncludePaths ++ protocOptions ++ schemas.map(_.getCanonicalPath),
         artifact =>
           throw new RuntimeException(
             s"The version of sbt-protoc you are using is incompatible with 
'${artifact}' code generator. Please update sbt-protoc to a version >= 
0.99.33"))
@@ -265,7 +272,7 @@ abstract class AbstractGenerateMojo @Inject() 
(buildContext: BuildContext) exten
 
       getLog.info("Compiling protobuf")
       val (out, err, exitCode) = captureStdOutAndErr {
-        executeProtoc(protocCommand, schemas, protoDir, protocOptions, 
generatedTargets)
+        executeProtoc(protocCommand, schemas, protocOptions, generatedTargets)
       }
       if (exitCode != 0) {
         err.split("\n\r").map(_.trim).map(parseError).foreach {


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to