Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to build Google protocol buffers and Kotlin using Gradle?

I'm trying to build a project that uses both Google protocol buffers and Kotlin using Gradle. I want the proto files to compile into Java source, which is then called from my Kotlin code.

My source files are arranged like this:

src/main/proto/*.proto
src/main/kotlin/*.kt
src/test/kotlin/*.kt

Here's my build.gradle file:

version '1.0-SNAPSHOT'

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

repositories {
    mavenCentral()
    maven { url "http://dl.bintray.com/kotlin/kotlin-eap-1.1" }
}


buildscript {
    ext.kotlin_version = '1.1-M02'

    repositories {
        mavenCentral()
        maven { url "http://dl.bintray.com/kotlin/kotlin-eap-1.1" }
    }

    dependencies {
        classpath 'com.google.protobuf:protobuf-gradle-plugin:0.8.0'
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
    }
}

protobuf {
    protoc {
        artifact = 'com.google.protobuf:protoc:3.0.0'
    }
}

dependencies {
    compile 'com.google.protobuf:protobuf-java:3.0.0'
    compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
    testCompile 'junit:junit:4.12'
}

When I run ./gradlew assemble I get a bunch of "Unresolved reference" errors during :compileKotlin. Afterwards I can see that there are no Java source files generated, so it appears that the proto compiler is not being invoked at all.

If I remove the apply plugin: 'kotlin' line, then ./gradlew assemble successfully generates the Java source, but of course my Kotlin source is never compiled.

How do I fix my build.gradle so that I can call my protobuf code from Kotlin?

like image 262
Laurence Gonsalves Avatar asked Nov 09 '16 02:11

Laurence Gonsalves


People also ask

How do I compile a proto file in gradle?

Enable the setting with: Settings -> Build, Execution, Deployment -> Build Tools -> Gradle -> Runner -> Delegate IDE build/run actions to gradle. This plugin integrates with the idea plugin and automatically registers the proto files and generated Java code as sources.

Does Google use Protobuf?

Protocol buffers, or Protobuf, is a binary format created by Google to serialize data between different services. Google made this protocol open source and now it provides support, out of the box, to the most common languages, like JavaScript, Java, C#, Ruby and others.

What languages does Protobuf support?

Protocol buffers currently support generated code in Java, Python, Objective-C, and C++. With our new proto3 language version, you can also work with Kotlin, Dart, Go, Ruby, and C#, with more languages to come.


2 Answers

I was able to get this to work by adding two lines to my build.gradle.

The first line adds the directory in which the proto compiler generates Java code to the directories the :compileKotlin looks for Java source:

sourceSets.main.java.srcDirs += 'build/generated/source/proto/main/java'

The second ensures that the Java code is (re)generated before invoking :compileKotlin:

compileKotlin.dependsOn ':generateProto'
like image 151
Laurence Gonsalves Avatar answered Sep 20 '22 08:09

Laurence Gonsalves


For Kotlin and Android:

android {

    sourceSets {
        debug.java.srcDirs += 'build/generated/source/proto/debug/java'
        release.java.srcDirs += 'build/generated/source/proto/release/java'
    }
}

An additional source directory has to be added for every build type. In this sample there are two build types: debug and release.

If you're using grpc, another line has to be added per build type:

android {

    sourceSets {
        debug.java.srcDirs += 'build/generated/source/proto/debug/java'
        debug.java.srcDirs += 'build/generated/source/proto/debug/grpc'
        release.java.srcDirs += 'build/generated/source/proto/release/java'
        release.java.srcDirs += 'build/generated/source/proto/release/grpc'
    }
}

At least with Kotlin 1.0.6, protobuf-gradle-plugin 0.8.0, protobuf 3.2.x and grpc 1.x it's not required to fiddle with the task order.

like image 22
aha Avatar answered Sep 21 '22 08:09

aha