在IntelliJ中使用Gradle导入由Protobuf生成的类

7
我遇到了使用Gradle导入Protobuf生成的类的问题。
这是我的项目树的样子:

Project tree:

我尝试将软件包标记为源代码,我尝试了所有可能的导入组合:

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目录下。

4个回答

7

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

Protobuf插件假设Protobuf文件(*.proto)与Java源文件相同,位于sourceSets中。一个sourceSet的Protobuf文件将被编译为单个protoc运行,并将生成的文件添加到该sourceSet的Java编译运行的输入中。

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

4

可能会有点不同,因为我是在 Android 项目中完成的,但对我有效的方法是在根 build.gradle 中添加 classpath "com.google.protobuf:protobuf-gradle-plugin:0.8.1",并在应用程序的 build.gradle 中添加以下内容。

另外,请不要忘记运行 gradle build,因为仅运行不会自动生成类,除非您已经在编译器选项中选择了 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制作了两个基本但可工作的示例,可能可以帮助您。使用Maven的Java示例项目(如果您愿意切换到Maven)。以及一个基本的使用gradle的Android示例项目,尽管有一些小差异(我使用java-lite和okhttp而不是netty)。


3

当我使用sbt时一切都正常,但在intellij中却遇到了同样的问题,这只是IDE高亮显示的问题。我不得不进入“项目结构” -> “模块” -> 点击“根” ->“依赖项” ->底部的“+”符号 -> Jars或目录 ->将生成的目录添加为依赖项。


你所说的“root”,是指“项目根目录”吗?在我的情况下,它被命名为其他名称。 - Michael Fulton
这是唯一对我有效的方法,非常感谢。 - ErrorrrDetector

-2
如果您想要为Java生成代码,您需要在proto文件中指定一个包名,例如:
option java_package = "com.example";

这样做然后再生成。

现在像这样导入:

`import com.example.HelloRequest;`

这并没有解决问题。我仍然无法在main/src/java中导入生成的文件。 - Alexandru Cancescu
1
不确定为什么这个被踩了,但是对我来说确实解决了问题。我的生成的 .java 文件没有包名,在 .proto 文件中定义了 java_package 后,.java 文件就有了一个定义好的包名,然后 intelliJ 就能够立即导入它了。我猜有两个不同的问题涉及到导入 protobuff 生成的类。这个答案解决了我的问题。 - diegoubi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接