2017-08-01 567 views
1

我正在使用protobuf在我的Android客戶端中自動生成我的API服務,在gRPC技術中。自從我一直在努力解決問題以來,已經有好幾個月了。現在突然間,AndroidRuntime驗證程序正在拒絕我的API的自動生成方法之一。java.lang.VerifyError:驗證程序拒絕的類 - 未能驗證


這裏是堆棧跟蹤:

com.company.companyplayer E/AndroidRuntime: FATAL EXCEPTION: main 
             Process: com.company.companyplayer, PID: 18181 
             java.lang.VerifyError: Verifier rejected class company.v1.PlayerEarningsPageDataResponse: void company.v1.PlayerEarningsPageDataResponse.mergeNextDepositDate(com.google.protobuf.Timestamp) failed to verify: void company.v1.PlayerEarningsPageDataResponse.mergeNextDepositDate(com.google.protobuf.Timestamp): [0x26] register v5 has type Precise Reference: com.google.protobuf.Timestamp but expected Reference: com.google.protobuf.GeneratedMessageLiteVerifier rejected class company.v1.PlayerEarningsPageDataResponse: java.lang.Object company.v1.PlayerEarningsPageDataResponse.dynamicMethod(com.google.protobuf.GeneratedMessageLite$MethodToInvoke, java.lang.Object, java.lang.Object) failed to verify: java.lang.Object company.v1.PlayerEarningsPageDataResponse.dynamicMethod(com.google.protobuf.GeneratedMessageLite$MethodToInvoke, java.lang.Object, java.lang.Object): [0x16E] register v8 has type Precise Reference: com.google.protobuf.Timestamp but expected Reference: com.google.protobuf.GeneratedMessageLite (declaration of 'company.v1.PlayerEarningsPageDataResponse' appears in /data/app/com.company.companyplayer-1/split_lib_slice_4_apk.apk) 
              at company.v1.PlayerEarningsPageDataResponse.getDefaultInstance(PlayerEarningsPageDataResponse.java:0) 
              at company.v1.APIGrpc.<clinit>(APIGrpc.java:47) 
              at company.v1.APIGrpc.newStub(APIGrpc.java:0) 
              at com.company.companyplayer.backend.Client.getAuthAsyncStub(Client.java:103) 
              at com.company.companyplayer.backend.Client.playerLogin(Client.java:119) 
              at com.company.companyplayer.ui.activity.LoginActivity.loginAndGoToMainActivity(LoginActivity.java:202) 
              at com.company.companyplayer.ui.activity.LoginActivity.onActivityResult(LoginActivity.java:127) 
              at android.app.Activity.dispatchActivityResult(Activity.java:6935) 
              at android.app.ActivityThread.deliverResults(ActivityThread.java:4086) 
              at android.app.ActivityThread.handleSendResult(ActivityThread.java:4133) 
              at android.app.ActivityThread.-wrap20(ActivityThread.java) 
              at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1534) 
              at android.os.Handler.dispatchMessage(Handler.java:102) 
              at android.os.Looper.loop(Looper.java:154) 
              at android.app.ActivityThread.main(ActivityThread.java:6121) 
              at java.lang.reflect.Method.invoke(Native Method) 
              at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:889) 
              at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:779) 

以下(解決方案類似的建議SO帖)沒有工作:

  • 清潔和重新建立(甚至嘗試手動清洗)
  • 的Invalidate緩存&重新啓動IDE
  • 從原
  • 重新生成API定義

另外,這裏是自動生成的方法在堆棧跟蹤中指出:

private void mergeNextDepositDate(com.google.protobuf.Timestamp value) { 
    if (nextDepositDate_ != null && nextDepositDate_ != com.google.protobuf.Timestamp.getDefaultInstance()) { 
     nextDepositDate_ = com.google.protobuf.Timestamp.newBuilder(nextDepositDate_).mergeFrom(value).buildPartial(); 
    } else { 
     nextDepositDate_ = value; 
    } 
    } 

它可以可以看出該方法既不是很長,也不需要太多的參數;有人說這是造成這個錯誤的常見原因。


以下是我的應用程序中的build.gradle:

apply plugin: 'com.android.application' 
apply plugin: 'com.google.protobuf' 

android { 
    compileSdkVersion 25 
    buildToolsVersion '25.0.3' 
    defaultConfig { 
     applicationId "com.company.companyplayer" 
     minSdkVersion 15 
     targetSdkVersion 25 
     versionCode 5 
     versionName "0.1" 
     testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 
     multiDexEnabled true 
     vectorDrawables.useSupportLibrary = true 
    } 
    buildTypes { 
     release { 
      minifyEnabled false 
      proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 
      signingConfig signingConfigs.config 
     } 
    } 
    lintOptions { 
     disable 'InvalidPackage' 
    } 
} 

protobuf { 
    protoc { 
     artifact = 'com.google.protobuf:protoc:3.2.0' 
    } 
    plugins { 
     javalite { 
      artifact = "com.google.protobuf:protoc-gen-javalite:3.0.0" 
     } 
     grpc { 
      artifact = 'io.grpc:protoc-gen-grpc-java:1.3.0' 
     } 
    } 
    generateProtoTasks { 
     all().each { task -> 
      task.plugins { 
       javalite {} 
       grpc { 
        // Options added to --grpc_out 
        option 'lite' 
       } 
      } 
     } 
    } 
} 

dependencies { 
    compile fileTree(include: ['*.jar'], dir: 'libs') 
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { 
     exclude group: 'com.android.support', module: 'support-annotations' 
    }) 
    /* android support libraries */ 
    compile 'com.google.android:flexbox:0.2.7' 
    compile 'com.android.support:multidex:1.0.1' 
    compile 'com.google.firebase:firebase-config:11.0.1' 
    compile 'com.google.firebase:firebase-core:11.0.1' 
    compile 'com.google.firebase:firebase-messaging:11.0.1' 
    compile 'com.google.android.gms:play-services-maps:11.0.1' 
    compile 'com.google.android.gms:play-services-location:11.0.1' 
    compile 'com.google.maps.android:android-maps-utils:0.4.4' 
    compile 'com.google.code.findbugs:jsr305:3.0.1' 
    compile 'io.grpc:grpc-okhttp:1.3.0' 
    compile 'io.grpc:grpc-protobuf-lite:1.3.0' 
    compile 'io.grpc:grpc-stub:1.3.0' 
    compile 'com.facebook.android:facebook-android-sdk:[4,5)' 
    compile 'com.facebook.android:account-kit-sdk:4.22.0' 
    compile 'javax.annotation:javax.annotation-api:1.2' 
    compile 'com.google.api.grpc:googleapis-common-protos:0.0.3' // This is for importing "google/api/annotations.proto" in our proto file 
    testCompile 'junit:junit:4.12' 
    androidTestCompile 'com.google.code.findbugs:jsr305:3.0.1' 
    protobuf 'com.google.protobuf:protobuf-java:3.1.0' 
} 

apply plugin: 'com.google.gms.google-services' 

(什麼都沒有的,因爲的gradle這一切工作正常,最後一次被改變)更新:該錯誤肯定與google.protobuf.Timestamp有關。這裏是link to an MWE,再現這個問題。

+0

難道你得到充分的protobuf作爲一個依賴偶然?我假設你想使用protobuf lite。運行'./gradlew dependencies'並確保你只有com.google.protobuf:protobuf-lite依賴關係,而不是com.google.protobuf:protobuf-java –

+0

@EricAnderson在我的gradle中有很多protobuf相關的條目,大多數其中一個'精簡版'。由於我不確定你說的是哪一個,所以我將我的build.gradle添加到上面的問題中。 –

回答

3

您正在混合lite和完整protobuf。

您不能在編譯或運行時依賴於googleapis-common-protos,因爲它是生成完整protobuf的代碼,它不適用於lite protobuf。它還引入了對protobuf-java的依賴,當與protobuf-lite混合在一起時會導致重複的類。代替編譯依賴性,使用protobuf依賴性讓protobuf gradle插件生成包含在JAR中的代碼.proto

您目前對protobuf-lite也沒有任何依賴性,所以如果沒有常見原型依賴性,您將會遇到編譯失敗。常見原型也引入了所需的grpc-protobuf-lite依賴關係。我建議在io.grpc:grpc-protobuf-lite:1.3.0上增加一個編譯時間依賴關係,這也將帶來protobuf-lite

因此,在短期,進行這些更改的項目,它編譯:

diff --git a/app/build.gradle b/app/build.gradle 
index 8f606bb..2fb997b 100644 
--- a/app/build.gradle 
+++ b/app/build.gradle 
@@ -62,7 +62,8 @@ dependencies { 
    compile 'javax.annotation:javax.annotation-api:1.2' 
    compile 'io.grpc:grpc-stub:1.3.0' 
    compile 'io.grpc:grpc-okhttp:1.3.0' 
+ compile 'io.grpc:grpc-protobuf-lite:1.3.0' 

- compile 'com.google.api.grpc:googleapis-common-protos:0.0.3' 
+ protobuf 'com.google.api.grpc:googleapis-common-protos:0.0.3' 
    protobuf 'com.google.protobuf:protobuf-java:3.1.0' 
}