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

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

commit b4167cd98e328e2c57b28f6068a27a22817d5701
Author: 虎鸣 <[email protected]>
AuthorDate: Fri Jul 3 04:06:57 2026 +0800

    fix: pass all protoPaths as -I import params to protoc in Maven plugin
    
    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