疑难杂症:Android 11上的Caused by: java.lang.VerifyError

1.编译报错具体内容

我们app的中间层核心sdk是一个自己编译的jar包,几年以来各类机型一直都没有出现过Caused by: java.lang.VerifyError的报错,如图所示:

疑难杂症:Android 11上的Caused by: java.lang.VerifyError_第1张图片

直到2021年中旬开始有客户反馈集成了我们的插件包(包含该jar)后,在android 11系统的手机上必然崩溃,通过错误日志文件可以看到是一个类型检查错误,即上图所示的Caused by: java.lang.VerifyError,具体表现是找不到getCooperateService()方法返回的对象(一个aidl文件生成的类)。

2.排查原因

同事排查了一周,依然没找到原因,google上也搜索不到针对这个报错的具体解决方案(回头来看google的解答,是因为这个报错本身是Android 11引发的,但是反馈的问题都有差异)。开始介入,辅助排查,只要target目标升级为30,编译阶段就报这个错了。仔细回溯我们sdk的源码,有多个类似获取aidl的对象的方法,不免想到为何唯独这个service方法返回的类对象找不到,而其他的同类型service方法获取正常。jartool工具反编译解析jar包,发现源文件中唯独缺失ICooperateService这个java类文件,原因已经找到,解决问题的思路也就有了。

3.解决办法

既然缺失这个类文件,肯定是编译jar的时候没有生成,仔细检查编译脚本,发现这个类所在模块的编译脚本一直就没有生成这个模块的class文件,导致最终合并生产jar时缺失需要的类。修正编译脚本,build出该模块所有class类即可。

4.反思

那以前(android 11)为什么是正常编译呢,即使缺少这个类文件。猜测是android 11系统对缺失文件检查更严格了(之前也有同事去查看了android 11的行为变更,对aidl文件确实有一个变更说明,但按照官方适配后问题依旧)。事后google资料寻找原因说明,基本也是验证了这个推测。详见google官方针对此类问题反馈的Bug说明,截引如下:

The full verification error is:    

Caused by: java.lang.VerifyError: Verifier rejected class com.sun.mail.handlers.handler_base: 
java.awt.datatransfer.DataFlavor[] com.sun.mail.handlers.handler_base.getTransferDataFlavors() 
failed to verify: java.awt.datatransfer.DataFlavor[] 
com.sun.mail.handlers.handler_base.getTransferDataFlavors(): [0x4]  can't resolve returned type 
'Unresolved Reference: java.awt.datatransfer.DataFlavor[]' or 'Reference: 
javax.activation.ActivationDataFlavor[]' (declaration of 'com.sun.mail.handlers.handler_base' appears 
in /data/app/~~RLNZ6uodnEsYCb6GewenIg==/com.example.testjavamail-
YKeE7WfbGlx0yA3z6ZNvGA==/base.apk)

This is WAI. In SDK 30, we've added a check to ensure the returned type is resolved. java.awt.* and 
javax.activation.* aren't APIs from Android, so unless you put them in your app, it's expected that they 
don't resolve. And even though the method at fault may never be executed, in SDK30 we've made 
things more strict on the return type for correctness.

If indeed you don't define java.awt.datatransfer.DataFlavor and/or  
javax.activation.ActivationDataFlavor in your app, I suggest you just remove the method referencing 
those classes. It is likely dead code.

同类问题反馈参见:

https://github.com/eclipse-ee4j/mail/issues/489

简单说就是Android 11在对象返回的检查时比之前更严格了。具体严格在哪没有提及。有赖分析源码。

另:谷歌官方收到的Bug反馈是调用com.sun.mail库时发生的,有的人是通过改变混淆文件来解决的:

疑难杂症:Android 11上的Caused by: java.lang.VerifyError_第2张图片

但升级库版本的解决方式应该是更靠谱的:

疑难杂症:Android 11上的Caused by: java.lang.VerifyError_第3张图片

你可能感兴趣的:(Java,Android,android)