【问题标题】:Import Protobuf generated classes using Gradle in IntelliJ在 IntelliJ 中使用 Gradle 导入 Protobuf 生成的类
【发布时间】:2026-01-16 03:05:02
【问题描述】:

我在使用 Gradle 导入 Protobuf 生成的类时遇到问题。

这是我的项目树的样子:

我已经尝试将包标记为 Source,我已经尝试了所有可能的导入组合:

import generated.main.grpc.GreeterGrpc;
import main.java.HelloRequest;
import java.*;
import HelloRequest;

它们都不起作用。这是我的 build.gradle:

group 'andu'
version '1.0-SNAPSHOT'

apply plugin: 'java'
apply plugin: 'com.google.protobuf'

sourceCompatibility = 1.5

repositories {
    mavenCentral()
    maven { url "https://plugins.gradle.org/m2/" }
}

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath 'com.google.protobuf:protobuf-gradle-plugin:0.8.0'
    }
}

dependencies {
    testCompile group: 'junit', name: 'junit', version: '4.11'
    compile 'io.grpc:grpc-protobuf:1.0.0-pre2'
    compile 'com.google.protobuf:protobuf-java:3.0.0'
    compile 'io.grpc:grpc-stub:1.0.0-pre2'
    compile 'io.grpc:grpc-netty:1.3.0'
    compile 'io.grpc:grpc-protobuf:1.3.0'
    compile 'io.grpc:grpc-stub:1.3.0'
}



sourceSets {
    main {
        proto {
            srcDir 'src/main/proto'
        }
        java {
            srcDirs =  ['src/main/java', 'generated/main/java']
        }
    }
}

protobuf {
    protoc {
        artifact = "com.google.protobuf:protoc:3.2.0"
    }
    plugins {
        grpc {
            artifact = 'io.grpc:protoc-gen-grpc-java:1.3.0'
        }
    }

    generateProtoTasks.generatedFilesBaseDir = 'generated'

    generateProtoTasks {
        all()*.plugins {
            grpc {}
        }
    }
}

在我添加之前

generateProtoTasks.generatedFilesBaseDir = 'generated'

我生成的所有类都将添加到 build/generated/main/java

【问题讨论】:

    标签: java intellij-idea gradle protocol-buffers grpc


    【解决方案1】:

    来自:https://medium.com/@DivyaJaisawal/generate-java-code-from-proto-file-using-gradle-1fb9fe64e046

    Protobuf 插件假定 Protobuf 文件 (*.proto) 在 sourceSets 中的组织方式与 Java 源文件相同。 sourceSet 的 Protobuf 文件在单个 protoc 运行中编译,生成的文件将添加到该 sourceSet () 的 Java 编译运行的输入中。

    sourceSets {
        main {
            java {
                srcDirs 'build/generated/source/proto/main/grpc'
                srcDirs 'build/generated/source/proto/main/java'
            }
        }
    }
    

    【讨论】:

      【解决方案2】:

      由于我是在 Android 项目中执行此操作的,因此可能会有些不同,但对我有用的是在我的根 build.gradle 中添加 classpath "com.google.protobuf:protobuf-gradle-plugin:0.8.1" 并在应用程序 build.gradle 中添加以下内容。

      另外不要忘记运行 gradle 构建,因为仅运行不会自动生成类,除非您在编译器选项中选择了 build project automatically option

      apply plugin: 'com.google.protobuf'
      
      protobuf {
          generatedFilesBaseDir = "$projectDir/generated"
          protoc {
              artifact = 'com.google.protobuf:protoc:3.0.0'
          }
          plugins {
              javalite {
                  artifact = "com.google.protobuf:protoc-gen-javalite:3.0.0"
              }
              grpc {
                  artifact = 'io.grpc:protoc-gen-grpc-java:1.0.3'
              }
          }
          generateProtoTasks {
              all().each { task ->
                  task.builtins {
                      java
                  }
                  task.plugins {
                      grpc {}
                  }
              }
          }
      }
      
      //Protobuf
      compile 'com.google.protobuf:protobuf-lite:3.0.0'
      compile 'com.google.protobuf:protobuf-java:3.0.0'
      
      //GRPC
      compile('io.grpc:grpc-protobuf:1.1.1') {
          exclude module: 'jsr305'
      }
      compile('io.grpc:grpc-okhttp:1.1.1') {
          exclude module: 'jsr305'
      }
      compile('io.grpc:grpc-stub:1.1.1') {
          exclude module: 'jsr305'
      }
      

      我还使用 gRPC 制作了两个基本但有效的示例,它们可能会有所帮助。 Example Java project 使用 Maven(如果您愿意切换到 Maven)。还有一个基本的Example Android project 使用 gradle,虽然有细微的差别(我使用的是 java-lite 和 okhttp 而不是 netty)。

      【讨论】:

        【解决方案3】:

        我在 intellij 中遇到了同样的问题,而在 sbt 中一切正常,只是在 IDE 中突出显示它的问题。我必须转到“项目结构”->“模块”->单击“根”->“依赖项”->底部的“+”符号->罐子或目录->将生成的目录添加为依赖项。

        【讨论】:

        • “根”是指“项目的根”。就我而言,它被命名为其他名称。
        【解决方案4】:

        如果你想为java生成,你必须在你的proto文件中提到一个包名,如下所示:

        option java_package = "com.example";
        

        这样做并再次生成。

        现在像这样导入:

        `import com.example.HelloRequest;`
        

        【讨论】:

        • 这并不能解决问题。我仍然无法在 main/src/java 中导入生成的文件
        • 不知道为什么这被否决了,这确实为我解决了。我生成的 .java 没有包,在 .proto 文件中定义 java_package 之后,.java 定义了一个包,并且 IntelliJ 立即能够导入它。我猜关于导入 protobuff 生成的类有 2 个不同的问题。这个回答解决了我的问题。