【发布时间】: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)
【问题讨论】:
标签: android evernote android-r8