天天看點

混淆jar包 作為依賴工程 打包混淆出錯 Unknown verification type [96] in stack map frame

[2014-08-23 13:02:57 - RankListDemo] Proguard returned with error code 1. See console

[2014-08-23 13:02:57 - RankListDemo] java.io.IOException: Can't read [C:\Users\Will\Desktop\storesdk_proguard\store_sdk\LetvStoreSDK\libs\letvstoresdk.jar] (Can't process class [com/letv/tvos/appstore/ranklistsdk/widget/Test.class] (Unknown verification type [11] in stack map frame))

[2014-08-23 13:02:57 - RankListDemo] at proguard.InputReader.readInput(InputReader.java:230)

[2014-08-23 13:02:57 - RankListDemo] at proguard.InputReader.readInput(InputReader.java:200)

[2014-08-23 13:02:57 - RankListDemo] at proguard.InputReader.readInput(InputReader.java:178)

[2014-08-23 13:02:57 - RankListDemo] at proguard.InputReader.execute(InputReader.java:78)

[2014-08-23 13:02:57 - RankListDemo] at proguard.ProGuard.readInput(ProGuard.java:196)

[2014-08-23 13:02:57 - RankListDemo] at proguard.ProGuard.execute(ProGuard.java:78)

[2014-08-23 13:02:57 - RankListDemo] at proguard.ProGuard.main(ProGuard.java:492)

[2014-08-23 13:02:57 - RankListDemo] Caused by: java.io.IOException: Can't process class [com/letv/tvos/appstore/ranklistsdk/widget/Test.class] (Unknown verification type [11] in stack map frame)

[2014-08-23 13:02:57 - RankListDemo] at proguard.io.ClassReader.read(ClassReader.java:112)

[2014-08-23 13:02:57 - RankListDemo] at proguard.io.FilteredDataEntryReader.read(FilteredDataEntryReader.java:87)

[2014-08-23 13:02:57 - RankListDemo] at proguard.io.JarReader.read(JarReader.java:65)

[2014-08-23 13:02:57 - RankListDemo] at proguard.io.DirectoryPump.readFiles(DirectoryPump.java:65)

[2014-08-23 13:02:57 - RankListDemo] at proguard.io.DirectoryPump.pumpDataEntries(DirectoryPump.java:53)

[2014-08-23 13:02:57 - RankListDemo] at proguard.InputReader.readInput(InputReader.java:226)

[2014-08-23 13:02:57 - RankListDemo] ... 6 more

[2014-08-23 13:02:57 - RankListDemo] Caused by: java.lang.RuntimeException: Unknown verification type [11] in stack map frame

[2014-08-23 13:02:57 - RankListDemo] at proguard.classfile.io.ProgramClassReader.createVerificationType(ProgramClassReader.java:890)

[2014-08-23 13:02:57 - RankListDemo] at proguard.classfile.io.ProgramClassReader.visitFullFrame(ProgramClassReader.java:659)

[2014-08-23 13:02:57 - RankListDemo] at proguard.classfile.attribute.preverification.FullFrame.accept(FullFrame.java:114)

[2014-08-23 13:02:57 - RankListDemo] at proguard.classfile.io.ProgramClassReader.visitStackMapTableAttribute(ProgramClassReader.java:452)

[2014-08-23 13:02:57 - RankListDemo] at proguard.classfile.attribute.preverification.StackMapTableAttribute.accept(StackMapTableAttribute.java:71)

[2014-08-23 13:02:57 - RankListDemo] at proguard.classfile.io.ProgramClassReader.visitCodeAttribute(ProgramClassReader.java:422)

[2014-08-23 13:02:57 - RankListDemo] at proguard.classfile.attribute.CodeAttribute.accept(CodeAttribute.java:101)

[2014-08-23 13:02:57 - RankListDemo] at proguard.classfile.io.ProgramClassReader.visitProgramMethod(ProgramClassReader.java:200)

[2014-08-23 13:02:57 - RankListDemo] at proguard.classfile.io.ProgramClassReader.visitProgramClass(ProgramClassReader.java:142)

[2014-08-23 13:02:57 - RankListDemo] at proguard.classfile.ProgramClass.accept(ProgramClass.java:346)

[2014-08-23 13:02:57 - RankListDemo] at proguard.io.ClassReader.read(ClassReader.java:91)

[2014-08-23 13:02:57 - RankListDemo] ... 11 more

前幾天做一個推廣SDK 遇到的一個問題,我們的SDK是以Library的形式提供給三方應用的,而代碼又不好不進行混淆處理就發給三方應用,是以我們的處理是

把源碼也就是src目錄下的所有檔案導出并做成一個jar包,然後對這個jar包進行混淆,然後再把這個混淆後的jar包放在library的libs目錄下面。問題的出現時在

一個三方使用者接入後,需要對自己的代碼進行混淆,生成一個簽名apk的時候。報了類似以上的一個錯誤,看錯誤日志,發現Test.class加載不了,也就是說Test.class 這個類

有問題,當我不對我的jar包進行混淆是,就不會報上面的錯誤。但我明顯在對我的jar包混淆的時候keep了這個類,然後我也讓接入的哥們,在他們的混淆腳本中以這樣的形式 -libraryjars 引入了我們的jar包,并且keep了個jar包下所有的類。 然後我就百度 谷歌 stackoverflow各種 搜尋,搜尋到今天我也沒有找到解決問題的方法。網絡上這個問題抛出來的也很久了,也有很多類似的問題,但問題就是沒有一個人真正意思的找到了解決這個問題的辦法,基本上都是-libraryjars keep dontwarn 之類的解決辦法。然後當時那邊也催的緊,當時報錯的是一個自定義控件,代碼量很多,就放棄了用哪個自定義控件,然後就選擇了另外的一種實作方案,後面三方應用接入的時候混淆也通過了。

然後最近這幾天也一直被這個問題困擾,然後趁着周末,思來想去還是想一探究竟,那個類到底怎麼了。然後就單獨把那個類拿出來,做成jar包,然後混淆,然後再以libray的形式提供,然後主工程代碼混淆導出簽名apk報的是同樣的錯,然後以大面積注釋 掉,然後一塊塊在放開以這種最笨的方法來找到問題出在哪裡。在這樣弄了兩個多小時後終于找到,我這個工程中導緻混淆出錯的元兇了。然後寫了個測試工程驗證了一下之前的錯誤,發現确實是有問題 代碼如下:test函數就是元兇,那個handled作為傳回值

在if{}else{}塊就等于做了無用功,因為真正能決定handled的是test1() ,但是奇怪的是test1的傳回值如果是直接傳回true或者false的話,也不會出問題。問題就出在test1的傳回值也是得根據傳入的i來決定的,

 int i;

private boolean test(){

boolean handled=false;

if(i>0){

handled=false;

}else{

handled=true;

}

handled=test1(i);

return handled;

}

private boolean test1(int i){

return  i<0?true:false;

}

如果有這樣的代碼的話,就會出現上述問題,即使你代碼混淆的時候keep了這個類,還是會報上面的錯誤。

但是我剛才又做了一個測試把test1改成如下 test調用的時候test1(handled)

private boolean test1(boolean i){

return  i;

}

然而又沒有出問題,如果傳test(true)的話,還是錯問題,是以我覺得應該是不能讓test

的if(i>0){

       handled=false;

}else{

      handled=true;

這段代碼做無用功,傳回值過多過少還是得依賴于if else 塊産生的handled ,說實話我也整懵了,編譯器的那些事

不是很了解,有誰知道原因的,幫忙在下面留言解答解答。