junglie85
junglie85

Reputation: 1463

gRPC gradle :generateProto fails with directory not found when importing other proto definitions

I'm trying to compile some protobuf definitions as a gradle task, but get the following error with no source generation:

* What went wrong:
Execution failed for task ':generateProto'.
> protoc: stdout: . stderr: /Users/ash/IdeaProjects/kotlin/grpc/build/extracted-protos/main: warning: directory does not exist.
  service-definitions.proto:10:17: "Empty" is not defined.
  service-definitions.proto:10:33: "Empty" is not defined.
  service-definitions.proto:15:17: "SimpleRequest" is not defined.
  service-definitions.proto:15:41: "SimpleResponse" is not defined.
  service-definitions.proto:21:27: "StreamingOutputCallRequest" is not defined.
  service-definitions.proto:21:71: "StreamingOutputCallResponse" is not defined.
  service-definitions.proto:27:33: "StreamingInputCallRequest" is not defined.
  service-definitions.proto:27:69: "StreamingInputCallResponse" is not defined.
  service-definitions.proto:34:29: "StreamingOutputCallRequest" is not defined.
  service-definitions.proto:34:73: "StreamingOutputCallResponse" is not defined.
  service-definitions.proto: warning: Import empty.proto but not used.
  service-definitions.proto: warning: Import messages.proto but not used.

This only occurs when I try to compile a definition that imports other definitions. If I remove the service-definitions.proto definition, the others compile and sources are generated.

The protobuf definitions are available from the vertx-grpc examples and I have them in $projectDir/src/main/proto. I've not changed their default build location, so sources are being generated to $projectDir/build/generated/source/proto. Instead of an extracted-protos directory, however, I have extracted-include-protos (probably explains the directory not found error).

Here's my gradle.build file, should it be of use. Note that the gRPC plugin uses the Vert.x artifact rather than the version from io.grpc.. (it's actually just a wrapper over the top of it). I have tried swapping the Vert.x version out for the io.grpc version and get the same error.

group 'grpc'
version '1.0-SNAPSHOT'

buildscript {
    ext.kotlin_version = '1.1.3'

    repositories {
        jcenter()
    }
    dependencies {
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
        classpath "com.google.protobuf:protobuf-gradle-plugin:0.8.1"
    }
}

apply plugin: 'kotlin'
apply plugin: "java"
apply plugin: "com.google.protobuf"
apply plugin: "idea"

protobuf {
    //generatedFilesBaseDir = "$projectDir/build/generated/source/proto"
    protoc {
        artifact = "com.google.protobuf:protoc:3.3.0"
    }
    plugins {
        grpc {
            artifact = "io.vertx:protoc-gen-grpc-java:1.3.0"
        }
    }
    generateProtoTasks {
        all().each { task ->
            task.plugins {
                grpc {}
            }
        }
    }
}

clean {
    delete protobuf.generatedFilesBaseDir
}

idea {
    module {
        sourceDirs += file("${protobuf.generatedFilesBaseDir}/main/java")
        sourceDirs += file("${protobuf.generatedFilesBaseDir}/main/grpc")
    }
}

sourceSets {
    main {
        java {
            srcDirs += "${protobuf.generatedFilesBaseDir}/main/java"
            srcDirs += "${protobuf.generatedFilesBaseDir}/main/grpc"
        }
    }
}

repositories {
    jcenter()
}

dependencies {
    compile "org.jetbrains.kotlin:kotlin-stdlib-jre8:$kotlin_version"
    compile "io.vertx:vertx-core:3.4.2"
    compile "io.vertx:vertx-web:3.4.2"
    compile "io.vertx:vertx-grpc:3.4.2"
}

compileKotlin {
    kotlinOptions {
        jvmTarget = "1.8"
        apiVersion = "1.1"
        languageVersion = "1.1"
    }
}
compileTestKotlin {
    kotlinOptions {
        jvmTarget = "1.8"
        apiVersion = "1.1"
        languageVersion = "1.1"
    }
}

I've not changed any settings, why is it (a) looking for extracted files in the wrong location, and (b) looking for extracted files at all when importing, given that the necessary definitions are all in the src/main/proto directory?

Upvotes: 0

Views: 2493

Answers (1)

junglie85
junglie85

Reputation: 1463

Okay, after much head scratching, the clue was in the last two lines of the error message:

service-definitions.proto: warning: Import empty.proto but not used.
service-definitions.proto: warning: Import messages.proto but not used.

In my proto definitions, I had specified messages and empty to be in the messages package but hadn't qualified the types when used in the importing definition, which is in the services package. Alas, a simple change and it works:

package services;
service EmptyPingPongService {
  // One empty request followed by one empty response.
  rpc EmptyCall(Empty) returns (Empty);
}

Becomes:

package services;    
service EmptyPingPongService {
  // One empty request followed by one empty response.
  rpc EmptyCall(messages.Empty) returns (messages.Empty);
}

Upvotes: 1

Related Questions