Evernote Android SDK 库在 R8 下抛出 java.lang.VerifyError

Posted

技术标签:

【中文标题】Evernote Android SDK 库在 R8 下抛出 java.lang.VerifyError【英文标题】:Evernote Android SDK library throws java.lang.VerifyError under R8 【发布时间】:2019-12-16 12:14:12 【问题描述】:

面对臭名昭著的java.lang.VerifyError。最初问题出现在 Fabric 中。一旦设置minifyEnabled true 进行调试构建,就能够重现(使用相同的堆栈跟踪)。

Caused by java.lang.VerifyError: Verifier rejected class com.evernote.client.conn.mobile.TEvernoteHttpClient: void com.evernote.client.conn.mobile.TEvernoteHttpClient.cancel() failed to verify: void com.evernote.client.conn.mobile.TEvernoteHttpClient.cancel(): [0x6] 'this' argument 'Reference: org.apache.http.client.methods.HttpRequestBase' not instance of 'Reference: org.apache.http.client.methods.AbstractExecutionAwareRequest'
 void com.evernote.client.conn.mobile.TEvernoteHttpClient.flush() failed to verify: void com.evernote.client.conn.mobile.TEvernoteHttpClient.flush(): [0x7F] 'this' argument 'Reference: org.apache.http.impl.client.DefaultHttpClient' not instance of 'Reference: org.apache.http.impl.client.CloseableHttpClient' (declaration of 'com.evernote.client.conn.mobile.TEvernoteHttpClient' appears in base.apk)
       at com.evernote.client.android.ClientFactory.createNoteStoreClient + 85(ClientFactory.java:85)

我发现通常java.lang.VerifyError 问题被认为与要编译和运行的代码之间的差异有关。

情况并非如此,因为在禁用缩小时代码运行良好。

我认为可以帮助的方法是制定另一条规则,但我无法理解哪些类需要保留此错误详细信息。

我们已经在做

-keep class com.evernote.**  *; 
-keep interface com.evernote.**  *; 

-keep class org.apache.http.**  *; 
-keep interface org.apache.http.**  *; 

... 这些类不会以任何方式被修改。我已经使用-printusage ./full-r8-config.txt 指令检查了它并检查了输出。错误详细信息中提到的类不显示在那里。

1 天后更新: 这里发生的事情真的很奇怪。 到目前为止,我有一个经过验证的备份计划:切换回 proguard 修复问题。

但如果我想留在 R8,那就来吧:

使用-dontshrink-dontoptimize-dontobfuscate(同时使用三个)没有影响;

强制特定的 apache.http 版本依赖没有影响;

我检查了映射:Evernore SDK 和 Apache http 类都不会被混淆;

应用在 api22 设备(实际上是模拟器)上执行时出现问题;

一旦我设置了-dontobfuscate,我就可以调试代码了。一切顺利,直到 Evernote 的 ClientFactory#createUserStoreClient 决定实例化 TEvernoteHttpClient - 程序执行触及后一个类的构造函数的那一刻 - 抛出异常。

看起来一切顺利,但是这个验证器失败了。

后期更新:

作为 R8 的错误提交的问题:https://issuetracker.google.com/issues/139268389。如果遇到类似情况,请随意给它加注星标(所有代码都已到位,但抛出了VerifyError)

【问题讨论】:

【参考方案1】:

试着写下proguard规则。

-dontwarn com.evernote.client.conn.mobile.TAndroidTransport
-dontwarn com.evernote.client.conn.mobile.DiskBackedByteStore
-dontwarn com.evernote.client.conn.mobile.ByteStore 
-dontwarn org.apache.commons.codec.binary.Base64

【讨论】:

以上是关于Evernote Android SDK 库在 R8 下抛出 java.lang.VerifyError的主要内容,如果未能解决你的问题,请参考以下文章

php [evernote php] evernote api https://github.com/evernote/evernote-cloud-sdk-php #note

EVERNOTE 的 JAVASCRIPT SDK 问题

Evernote PHP SDK 未从 API 返回任何结果

Evernote Android API 坏了?共享文档的意图不再有效

JobDispacter vs Android-job(Evernote)

Android SDK目录及版本号区别