I am trying to develop GRPC on Android Mobile App. I found HelloWorld sample project from https://github.com/grpc/grpc-java/tree/v1.34.1/examples/android/helloworld
When I build the project, I got the following error:
import io.grpc.examples.helloworld.GreeterGrpc;
^
symbol: class GreeterGrpc
location: package io.grpc.examples.helloworld
I am trying to build the app with that gradle:
apply plugin: 'com.android.application'
apply plugin: 'com.google.protobuf'
android {
compileSdkVersion 28
defaultConfig {
applicationId "io.grpc.helloworldexample"
minSdkVersion 16
targetSdkVersion 28
versionCode 1
versionName "1.0"
}
buildTypes {
debug { minifyEnabled false }
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
lintOptions {
disable 'GoogleAppIndexingWarning', 'HardcodedText', 'InvalidPackage'
textReport true
textOutput "stdout"
}
}
protobuf {
protoc {
artifact = "com.google.protobuf:protoc:3.2.0"
}
plugins {
lite {
artifact = "com.google.protobuf:protoc-gen-javalite:3.0.0"
}
}
generateProtoTasks {
all().each { task ->
task.builtins {
remove java
}
task.plugins {
lite { }
}
}
}
}
dependencies {
implementation 'com.android.support:appcompat-v7:27.1.1'
implementation 'com.google.android.material:material:1.1.0-alpha09'
implementation 'io.grpc:grpc-okhttp:1.34.1'
implementation 'io.grpc:grpc-protobuf-lite:1.34.1'
implementation 'io.grpc:grpc-stub:1.34.1'
compileOnly 'org.apache.tomcat:annotations-api:6.0.53' // necessary for Java 9+
}
The proto file like that:
syntax = "proto3";
option java_multiple_files = true;
option java_package = "io.grpc.examples.helloworld";
option java_outer_classname = "HelloWorldProto";
option objc_class_prefix = "HLW";
package helloworld;
// The greeting service definition.
service Greeter {
rpc SayHello (HelloRequest) returns (HelloReply) {}
}
// The request message containing the user's name.
message HelloRequest {
string name = 1;
}
// The response message containing the greetings
message HelloReply {
string message = 1;
}
Is there any problem in the code or gradle file? Could you help me please? Thanks
The error indicates that you are missing the generated GreeterGrpc service code. You need to feed protoc compiler the gRPC-Java codegen plugin in order to get the generated gRPC code.
protobuf {
protoc { artifact = "com.google.protobuf:protoc:3.12.0" }
plugins {
grpc { artifact = "io.grpc:protoc-gen-grpc-java:1.34.1" }
}
generateProtoTasks {
all().each { task ->
task.builtins {
java { option 'lite' }
}
task.plugins {
grpc { // Options added to --grpc_out
option 'lite' }
}
}
}
}
Note I've changed to use protoc v3.12.0 in this case. If you are using protoc older than v3.8.0, it would be
protobuf {
protoc {
artifact = "com.google.protobuf:protoc:3.2.0"
}
plugins {
lite {
artifact = "com.google.protobuf:protoc-gen-javalite:3.0.0"
}
grpc {
// some old grpc version, newer ones may not work, suggest upgrading
artifact = "io.grpc:protoc-gen-grpc-java:1.22.3"
}
}
generateProtoTasks {
all().each { task ->
task.builtins {
remove java
}
task.plugins {
lite { }
grpc { // Options added to --grpc_out
option 'lite' }
}
}
}
}
Related
I try to compile proto definitions into kotlin stubs, but get import issues. My gradle is
protobuf {
protoc {
artifact = "com.google.protobuf:protoc:3.21.2"
}
plugins {
grpckt {
artifact = "io.grpc:protoc-gen-grpc-kotlin:1.3.0:jdk8#jar"
}
}
generateProtoTasks {
all().forEach { task ->
task.builtins {
grpckt {
option 'lite'
}
}
task.plugins {
kotlin {
option 'lite'
}
}
}
}
}
dependencies {
//grpc dependency
implementation("io.grpc:grpc-kotlin-stub:1.3.0")
implementation 'io.grpc:grpc-okhttp:1.47.0'
implementation("io.grpc:grpc-protobuf:1.47.0")
implementation("com.google.protobuf:protobuf-kotlin:3.21.12")
implementation 'io.grpc:grpc-protobuf-lite:1.47.0'
}
I have few proto files. After proto compiled I get the files with import errors:
option java_multiple_files = true - doesn`t help.
This is my protoc setup in build.gradle which works in gradle 4.2
protobuf {
protoc { artifact = 'com.google.protobuf:protoc:3.10.0' }
plugins {
javalite { artifact = "com.google.protobuf:protoc-gen-javalite:3.0.0" }
grpc { artifact = 'io.grpc:protoc-gen-grpc-java:1.25.0' // CURRENT_GRPC_VERSION
}
}
generateProtoTasks {
all().each { task ->
task.plugins {
javalite {}
grpc { // Options added to --grpc_out
option 'lite' }
}
}
}
}
How is it not building in only gradle 7.0?
The protoc setup for as described in the current documentation is:
protobuf {
protoc { artifact = 'com.google.protobuf:protoc:3.12.0' }
plugins {
grpc { artifact = 'io.grpc:protoc-gen-grpc-java:1.36.0' // CURRENT_GRPC_VERSION
}
}
generateProtoTasks {
all().each { task ->
task.builtins {
java { option 'lite' }
}
task.plugins {
grpc { // Options added to --grpc_out
option 'lite' }
}
}
}
}
The main difference from what you have is the lack of definition in task.plugins and setting mode 'lite' and using the grpc-java library and not the java-lite.
I am creating a Jetbrains Compose Multiplatform project. But I will only need Desktop (JVM) and Android, so two JVM targets. I want to factor out the logic which needs grpc, so both Android and Desktop can use it without me having to program it twice.
I can't seem to figure out a way of binding in my grpc/proto into the project, so that I can write the logic once and share it between android and desktop.
This is what my build.gradle.kts of the common project looks like:
plugins {
id("com.android.library")
kotlin("multiplatform")
id("org.jetbrains.compose")
}
kotlin {
android()
jvm("desktop")
sourceSets {
named("commonMain") {
dependencies {
api(compose.runtime)
api(compose.foundation)
api(compose.material)
api(compose.ui)
implementation(compose.preview)
implementation(compose.uiTooling)
}
}
}
}
android {
compileSdk = 31
defaultConfig {
minSdk = 21
targetSdk = 31
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
sourceSets {
named("main") {
manifest.srcFile("src/androidMain/AndroidManifest.xml")
res.srcDirs("src/androidMain/res")
}
}
}
I tried binding my protos into a sourceset but couldn't get it working.
My other approach:
Next I tried creating a second submodule where the protos and the logic would be bound, but I couldn't get that working either:
Here is the build.gradle.kts for shared-logic:
import com.google.protobuf.gradle.*
import org.gradle.kotlin.dsl.proto
plugins {
kotlin("jvm")
idea
id("com.google.protobuf")
}
version = "unspecified"
repositories {
mavenCentral()
}
dependencies {
implementation(kotlin("stdlib"))
api(project(":kotlin-common")) {
exclude(group = "io.grpc", module = "grpc-protobuf")
exclude(group = "io.grpc", module = "grpc-stub")
}
implementation("io.grpc:grpc-okhttp:${Versions.GRPC}")
api("com.google.protobuf:protobuf-java-util:${Versions.PROTOBUF}")
api("io.grpc:grpc-stub:${Versions.GRPC}")
api("io.grpc:grpc-protobuf-lite:${Versions.GRPC}")
api("io.grpc:grpc-kotlin-stub:${Versions.GRPC_KOTLIN}")
api("com.google.protobuf:protobuf-kotlin-lite:${Versions.PROTOBUF}")
api("io.insert-koin:koin-core:${Versions.KOIN}")
api("org.jetbrains.kotlinx:kotlinx-coroutines-core:${Versions.COROUTINES}")
}
sourceSets {
main {
proto {
srcDirs("../protos/src/main")
}
}
}
protobuf {
protoc {
artifact = "com.google.protobuf:protoc:${Versions.PROTOBUF}"
}
plugins {
id("java") {
artifact = "io.grpc:protoc-gen-grpc-java:${Versions.GRPC}"
}
id("grpc") {
artifact = "io.grpc:protoc-gen-grpc-java:${Versions.GRPC}"
}
id("grpckt") {
artifact = "io.grpc:protoc-gen-grpc-kotlin:${Versions.GRPC_KOTLIN}:jdk7#jar"
}
}
generateProtoTasks {
all().forEach {
it.plugins {
id("grpc") {
option("lite")
}
id("grpckt") {
option("lite")
}
}
it.builtins {
id("kotlin") {
option("lite")
}
}
}
}
}
Here is the build.gradle.kts for kotlin-common:
plugins {
kotlin("jvm")
}
version = "1.0.0"
repositories {
mavenCentral()
}
dependencies {
implementation(kotlin("stdlib"))
implementation("io.grpc:grpc-stub:${Versions.GRPC}")
}
Here I get resolution error I tried fixing but couldn't figure out what to exclude:
Duplicate class com.google.protobuf.AbstractMessageLite found in modules jetified-protobuf-java-3.19.1 (com.google.protobuf:protobuf-java:3.19.1) and jetified-protobuf-javalite-3.19.1 (com.google.protobuf:protobuf-javalite:3.19.1)
Duplicate class com.google.protobuf.AbstractMessageLite$Builder found in modules jetified-protobuf-java-3.19.1 (com.google.protobuf:protobuf-java:3.19.1) and jetified-protobuf-javalite-3.19.1 (com.google.protobuf:protobuf-javalite:3.19.1)
Duplicate class com.google.protobuf.AbstractMessageLite$Builder$LimitedInputStream found in modules jetified-protobuf-java-3.19.1 (com.google.protobuf:protobuf-java:3.19.1) and jetified-protobuf-javalite-3.19.1 (com.google.protobuf:protobuf-javalite:3.19.1)
...
I created a gRPC server (hosted by AWS) in nodejs and I can connect to it with a nodejs client implementation from my local machine.
I'm using the com.google.protobuf plugin to auto generate code from my .proto file.
My gradle sync works and the app builds successfully but I can't find the generated code classes.
I'm struggling to find a good implementation example for a Kotlin for Android gRPC client but I followed these articles:
gRPC In Kotlin(Android)
Java Basic Tutorial
My app/src/main/protos/responder.proto file
syntax = "proto3";
option java_package = "protos.grpc";
package responder;
message ConnectionRequest {
int32 userId = 2;
}
message ConnectionResponse {
string response = 1;
}
service ResponderService {
rpc responderConnect (stream ConnectionRequest) returns (stream ConnectionResponse) {};
}
Project build.gradle
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
ext {
kotlin_version = '1.3.72'
protobufPluginVersion = '0.8.6'
grpcVersion = '1.12.0'
protocVersion = '3.2.0'
}
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.6.3'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath "com.google.protobuf:protobuf-gradle-plugin:$protobufPluginVersion"
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
def nav_version = "2.2.2"
classpath "androidx.navigation:navigation-safe-args-gradle-plugin:$nav_version"
}
}
allprojects {
repositories {
google()
jcenter()
maven { url "https://jitpack.io" }
mavenCentral()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
And my app's build.gradle
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'com.google.protobuf'
android {
compileSdkVersion 29
buildToolsVersion "29.0.3"
defaultConfig {
applicationId "organisation.responder.two"
minSdkVersion 19
targetSdkVersion 29
versionCode 31
versionName "2.0"
multiDexEnabled true
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = "1.8"
}
}
dependencies {
...
implementation 'io.grpc:grpc-okhttp:1.30.0'
implementation 'io.grpc:grpc-protobuf-lite:1.30.0'
implementation 'io.grpc:grpc-stub:1.30.0'
implementation 'io.grpc:grpc-core:1.30.0'
compileOnly 'org.apache.tomcat:annotations-api:6.0.53'
def multidex_version = "2.0.1"
implementation "androidx.multidex:multidex:$multidex_version"
}
protobuf {
protoc {
artifact = "com.google.protobuf:protoc:3.12.0"
}
plugins {
javalite {
artifact = "com.google.protobuf:protoc-gen-javalite:3.0.0"
}
grpc {
artifact = "io.grpc:protoc-gen-grpc-java:1.30.0"
}
}
generateProtoTasks {
all().each { task ->
task.builtins {
remove java
}
task.plugins {
javalite {}
grpc {
// Options added to --grpc_out
option 'lite'
}
}
}
}
}
As I said above, the gradle sync is successful and the project builds successfully. But where is the autogenerated code?
After following this build.gradle file as an example, I managed to generate the grpc code using the gradle protobuf plugin.
Major changes to my app level build.gradle file included:
Adding path to .proto file in sourceSets block under android block.
android {
...
sourceSets {
main {
proto {
srcDir 'src/main/protos' <-- path to .proto file
}
}
}
}
Change the protobuf block in app level build.gradle file
protobuf {
protoc {
artifact = "com.google.protobuf:protoc:3.12.0"
}
plugins {
grpc {
artifact = "io.grpc:protoc-gen-grpc-java:1.30.0"
}
}
generateProtoTasks {
all().each { task ->
task.builtins {
remove javanano
java {
option 'lite'
}
}
task.plugins {
grpc {
// Options added to --grpc_out
option 'lite'
}
}
}
}
}
After a successful sync and build, the generated code files where located under app/build/generated/source/proto/debug/grpc/protos/grpc/ResponderServiceGrpc.java and app/build/generated/source/proto/debug/java/protos/grpc/Responder.java
While integrating protobuf into my android project, I am getting this error during gradle build:
Type com.google.protobuf.SourceContextOrBuilder is defined multiple times: /Users/kchaubal/.gradle/caches/transforms-2/files-2.1/4af300e60802588311eb01ecc52e7bea/jetified-protobuf-java-3.0.0.jar:com/google/protobuf/SourceContextOrBuilder.class, /Users/kchaubal/Dev/GitHubRepo/RPCExample/app/build/intermediates/javac/debug/classes/com/google/protobuf/SourceContextOrBuilder.class
This is how my grade file looks like
dependencies {
implementation 'io.grpc:grpc-okhttp:1.29.0'
protobuf 'io.grpc:grpc-protobuf-lite:1.29.0'
implementation 'io.grpc:grpc-stub:1.29.0'
implementation 'javax.annotation:javax.annotation-api:1.3.2'
implementation 'com.google.api.grpc:googleapis-common-protos:0.0.3'
}
protobuf {
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.29.0'
}
}
generateProtoTasks {
all().each { task ->
task.builtins {
remove java
}
task.plugins {
javalite { }
grpc { option 'lite' }
}
}
}
files("${protobuf.generatedFilesBaseDir}/main/proto")
}
I am a newbie with protobuf so any kind of help is much appreciated
dependencies {
...
protobuf 'com.google.protobuf:protobuf-java:3.7.1'
}