I am trying to implement gRPC and now I'm having all sorts of issues, but I just don't get what I'm doing wrong. I am following this doc:
https://github.com/grpc/grpc-java/blob/master/README.md
And now I keep getting such errors when I'm trying to build my project
error: package com.google.protobuf.GeneratedMessageV3 does not exist
com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
In my Android Studio external libraries I have protobuf-java-3.12.1 jar.
In my project gradle file I've added this to dependencies:
classpath 'com.google.protobuf:protobuf-gradle-plugin:0.8.14'
And in my app gradle file:
apply plugin: 'com.android.application'
apply plugin: 'com.google.protobuf'
In dependencies I added:
implementation 'io.grpc:grpc-okhttp:1.35.0'
implementation 'io.grpc:grpc-protobuf-lite:1.35.0'
implementation 'io.grpc:grpc-stub:1.35.0'
compileOnly 'org.apache.tomcat:annotations-api:6.0.53'
implementation 'com.google.protobuf:protobuf-javalite:3.12.1'
And outside of the android tag:
protobuf {
protoc {
artifact = "com.google.protobuf:protoc:3.12.1"
}
plugins {
grpc {
artifact = 'io.grpc:protoc-gen-grpc-java:1.35.0'
}
}
generateProtoTasks {
all()*.plugins {
grpc {}
}
}
}
Finally, my proto file:
syntax = "proto3";
import "google/protobuf/timestamp.proto";
option java_package = "com.xxx.xxx.proto.log";
option java_outer_classname = "MyClass";
message MyObject {
string name = 1;
string unit = 2;
oneof value {
bool bool_value = 3;
sint32 int32_value = 4;
uint32 u_int32_value = 5;
google.protobuf.Timestamp timestamp_value = 6;
}
}
When I run: protoc --version in terminal, this is the output:
libprotoc 3.12.1
Do I have to add something else or I missed something in my Gradle setup?
It looks like you are hoping to use protobuf lite (as is normal for Android projects):
implementation 'io.grpc:grpc-protobuf-lite:1.35.0'
...
implementation 'com.google.protobuf:protobuf-javalite:3.12.1'
However, currently you are generating full protobuf code. You need to tell the java and grpc-java code generators to generate for lite via options. As seen in the grpc-java Android helloworld example:
protobuf {
...
generateProtoTasks {
all().each { task ->
task.builtins {
java { option 'lite' }
}
task.plugins {
grpc { option 'lite' }
}
}
}
}
Related
I spend hours on just setting up Protobuf with Kotlin in Android Studio. The endgoal is just that my proto files are compiled in Kotlin and that I can use them in my project.
I have an example project here: https://github.com/Jasperav/ProtobufAndroid. It mimics my setup in the real application: an external dir containing the proto files and the android project. It contains all the code mentioned below. This is a combined effort of tutorials I found on the internet. It is probably terrible wrong. I tried https://github.com/google/protobuf-gradle-plugin, but it just looks so complicated for something simple I am doing:
Have a dir with protofiles somewhere on your filesystem
Create a new Android project on Kotlin
In the Project build.gradle, add id 'com.google.protobuf' version '0.9.2' apply false as plugin
In the Module build.gradle, add ->
This to the dependencies: implementation 'com.google.protobuf:protobuf-lite:3.21.12'
The sourceSets at the bottom inside the android bracket
The protobuf section at the bottom between the dependencies and android section.
sourceSets:
sourceSets {
main {
kotlin {
srcDirs += 'build/generated/source/proto/main/kotlin'
}
proto {
srcDir '/Users/me/androidkotlin/proto'
}
}
}
protobuf:
protobuf {
protoc {
artifact = 'com.google.protobuf:protoc:3.21.12'
}
plugins {
kotlinlite {
artifact = 'com.google.protobuf:protoc-gen-kotlin:3.21.12'
}
}
generateProtoTasks {
ofSourceSet("main").forEach { task ->
task.builtins {
getByName("kotlin") {
option("lite")
}
}
}
}
}
I get this error:
A problem occurred evaluating project ':app'.
> Could not find method proto() for arguments [build_cxwfo79b6zcc266x9rsqzou9f$_run_closure1$_closure8$_closure10$_closure12#203aac02] on source set main of type com.android.build.gradle.internal.api.DefaultAndroidSourceSet.
You are in a good way, but, there is some stuff missing:
The gradle code I'll share is written in Kotlin, just in case. If you can convert your grade files to Kotlin, nice, if not you have to convert them to groovy.
The first thing to check is if you have the proto folder in the right path, it should be in
root->app->src->main->proto
In the project gradle make sure to have the plugin applied
id("com.google.protobuf") version "0.8.15" apply false
In the app gradle, make sure to have the following.
import com.google.protobuf.gradle.*
plugins {
id("com.android.application")
id("org.jetbrains.kotlin.android")
id("com.google.protobuf")
}
The dependencies:
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.2")
implementation("com.google.protobuf:protobuf-kotlin:3.21.2")
implementation("io.grpc:grpc-stub:1.52.0")
implementation("io.grpc:grpc-protobuf:1.52.0")
implementation("io.grpc:grpc-okhttp:1.52.0")
implementation("com.google.protobuf:protobuf-java-util:3.21.7")
implementation("com.google.protobuf:protobuf-kotlin:3.21.2")
implementation("io.grpc:grpc-kotlin-stub:1.3.0")
And the protobuf task:
protobuf {
protoc {
artifact = "com.google.protobuf:protoc:${rootProject.ext["protobufVersion"]}"
}
plugins {
id("java") {
artifact = "io.grpc:protoc-gen-grpc-java:${rootProject.ext["grpcVersion"]}"
}
id("grpc") {
artifact = "io.grpc:protoc-gen-grpc-java:${rootProject.ext["grpcVersion"]}"
}
id("grpckt") {
artifact = "io.grpc:protoc-gen-grpc-kotlin:${rootProject.ext["grpcKotlinVersion"]}:jdk8#jar"
}
}
generateProtoTasks {
all().forEach {
it.plugins {
id("java") {
option("lite")
}
id("grpc") {
option("lite")
}
id("grpckt") {
option("lite")
}
}
it.builtins {
id("kotlin") {
option("lite")
}
}
}
}
}
These are the versions I'm using:
ext["grpcVersion"] = "1.47.0"
ext["grpcKotlinVersion"] = "1.3.0" // CURRENT_GRPC_KOTLIN_VERSION
ext["protobufVersion"] = "3.21.2"
ext["coroutinesVersion"] = "1.6.2"
Having that your project should generate the code based on your proto files.
For further reference, I recently build this Android App based on Kotlin + gRPC: https://github.com/wilsoncastiblanco/notes-grpc
First time using protobu and could not find an example of how to connect it to Kotlin Multiplatform. I created Multiplatform project Android/IOS with "shared" module where I need to use protobuf. Project structure:
Code in build.gradle shared.module lvl
build.gradle shared.module lvl
plugins {
kotlin("multiplatform")
id("com.android.library")
id("com.google.protobuf")
}
kotlin {
android()
listOf(
iosX64(),
iosArm64(),
iosSimulatorArm64()
).forEach {
it.binaries.framework {
baseName = "shared"
}
}
sourceSets {
val commonMain by getting {
dependencies {
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4")
}
}
val commonTest by getting {
dependencies {
implementation(kotlin("test"))
}
}
val androidMain by getting
val androidTest by getting
val iosX64Main by getting
val iosArm64Main by getting
val iosSimulatorArm64Main by getting
val iosMain by creating {
dependsOn(commonMain)
iosX64Main.dependsOn(this)
iosArm64Main.dependsOn(this)
iosSimulatorArm64Main.dependsOn(this)
}
val iosX64Test by getting
val iosArm64Test by getting
val iosSimulatorArm64Test by getting
val iosTest by creating {
dependsOn(commonTest)
iosX64Test.dependsOn(this)
iosArm64Test.dependsOn(this)
iosSimulatorArm64Test.dependsOn(this)
}
}
}
android {
namespace = "com.example.someproject"
compileSdk = 33
defaultConfig {
minSdk = 21
targetSdk = 33
}
protobuf {
protoc {
artifact = ("com.google.protobuf:protoc:3.21.9")
}
generateProtoTasks {
all().forEach { task ->
task.builtins {
java {
// option 'lite' //Error - Unresolved reference: option
}
kotlin {
// option 'lite' //Error - Unresolved reference: option
}
}
}
}
}
dependencies {
implementation("com.google.protobuf:protobuf-javalite:3.21.9")
}
}
My build.gradle project lvl:
build gradle project lvl
buildscript {
dependencies {
classpath 'com.google.protobuf:protobuf-gradle-plugin:0.9.1'
}
}
plugins {
id 'com.android.application' version '7.3.1' apply false
id 'com.android.library' version '7.3.1' apply false
id 'org.jetbrains.kotlin.android' version '1.7.20' apply false
id 'com.google.protobuf' version '0.9.1' apply false
}
I tried to add path to my .proto files with sourceSets, but I got errors:
android {
namespace = "com.example.someproject"
compileSdk = 33
defaultConfig {
minSdk = 21
targetSdk = 33
}
sourceSets {
main { //Error - Unresolved reference: main
proto { //Error - Unresolved reference: proto
srcDir 'src/main/protobuf' //Error - Unresolved reference: srcDir
}
java {
srcDirs 'build/generated/source/proto/main/java' //Error - Unresolved reference: srcDirs
srcDirs 'build/generated/source/proto/main/kotlin' //Error - Unresolved reference: srcDirs
}
}
}
protobuf {
protoc {
artifact = ("com.google.protobuf:protoc:3.21.9")
}
generateProtoTasks {
all().forEach { task ->
task.builtins {
java {
// option 'lite' //Error - Unresolved reference: option
}
kotlin {
// option 'lite' //Error - Unresolved reference: option
}
}
}
}
}
dependencies {
implementation("com.google.protobuf:protobuf-javalite:3.21.9")
}
}
When I try to build project without sourceSets, I didn't get generated java/kotlin files in build/generated/source - path
And my question is: "How setup protobuf in Android/IOS project Kotlin multiplatform?"
If you want to use ProtoBuf library in shared module in common code, then you have to use library that supports Kotlin Multiplatform. You can take a look at official kotlinx.serialization library, it supports ProtoBuf. And you can use it in commonMain module.
Also take a look at community library
Or learn more about platform-specific implementations and use expect/actual mechanism
Another option will be use your ProtoBuf library and plugin in androidApp only and for iOS part use another iOS specific ProtoBuf library.
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' }
}
}
}
}
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'
}
I'm trying to migrate to Android studio and my app engine code uses the Entity framework listed below
import javax.persistence.Entity;
import javax.persistence.Id;
#Entity
public class AppVersion {
#Id
private String applicationName;
private int minVersionRequired;
public String getApplicationName() {
return applicationName;
}
public int getMinVersionRequired() {
return minVersionRequired;
}
public void setApplicationName(String applicationName) {
this.applicationName = applicationName;
}
public void setminVersionRequired(int minVersionRequired) {
this.minVersionRequired = minVersionRequired;
}
}
Just creating a backend in Android Studio (0.5.6) doesn't work, I can't import javax.persistence.*
From this link I discovered that I needed to create a persistence.xml file (this was automatically created in Eclipse). I just can't figure out where in the file structure it is supposed to go. I understand it needs to be in the META-INF folder but I don't know where that corresponds for gradle (or if it has to be created in the gradle build file).
Current file structure:
-src
-main
-java
-com.package.test
class files
-webapp
-css
-js
-WEB-INF
Gradle build file:
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.google.appengine:gradle-appengine-plugin:1.9.1'
}
}
repositories {
mavenCentral();
}
apply plugin: 'java'
apply plugin: 'war'
apply plugin: 'appengine'
sourceCompatibility = 1.7
targetCompatibility = 1.7
dependencies {
appengineSdk 'com.google.appengine:appengine-java-sdk:1.9.1'
compile 'com.google.appengine:appengine-endpoints:1.9.1'
compile 'com.google.appengine:appengine-endpoints-deps:1.9.1'
compile 'javax.servlet:servlet-api:2.5'
}
appengine {
downloadSdk = true
appcfg {
oauth2 = true
}
endpoints {
getClientLibsOnBuild = true
getDiscoveryDocsOnBuild = true
}
}
Android Studio's App Engine samples don't use JPA.
However if you want to use JPA, you need to add the JPA dependencies, this describes where you might find out what those are https://developers.google.com/appengine/docs/java/datastore/jpa/overview-dn2
So these (or some subset of these)
asm-4.0.jar
datanucleus-api-jpa-3.1.3.jar
datanucleus-core-3.1.3.jar
jdo-api-3.0.1.jar
datanucleus-api-jdo-3.1.3.jar
datanucleus-appengine-2.1.2.jar
geronimo-jpa_2.0_spec-1.0.jar
jta-1.1.jar
Look on maven.org for those dependencies will reveal how to include them in build.gradle files as compile dependencies:
asm-4.0 :
compile 'org.ow2.asm:asm:4.0'
datanucleus-api-jpa-3.1.3 :
compile 'org.datanucleus:datanucleus-api-jpa:3.1.3'
and so on.
You want the versions to be exactly as they are in the appengine sdk to ensure compatibility. Also make sure you run the enhance task on your project.
Try adding following to the build.gradle
compile group: 'javax.persistence', name: 'persistence-api', version: '1.0'