编译使用ProGuard给出例外:"局部变量的类型不匹配" [英] Compile with Proguard gives Exception: "local variable type mismatch"

查看:242
本文介绍了编译使用ProGuard给出例外:"局部变量的类型不匹配"的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我编译我使用ProGuard Android应用程序使我得到以下错误:

When I compile my Android Application with Proguard enabled I get the following error:

-dex:
 [echo] Converting compiled files and external libraries into /home/ka/dev/workspace/ImPress/build/classes.dex...
[apply] 
[apply] UNEXPECTED TOP-LEVEL EXCEPTION:
[apply] com.android.dx.cf.code.SimException: local variable type mismatch: attempt to set or access a value of type java.io.File using a local variable of type java.lang.Object[]. This is symptomatic of .class transformation tools that ignore local variable information.
[apply]     at com.android.dx.cf.code.BaseMachine.throwLocalMismatch(BaseMachine.java:550)
[apply]     at com.android.dx.cf.code.BaseMachine.getLocalTarget(BaseMachine.java:405)
[apply]     at com.android.dx.cf.code.BaseMachine.storeResults(BaseMachine.java:532)
[apply]     at com.android.dx.cf.code.ValueAwareMachine.run(ValueAwareMachine.java:197)
[apply]     at com.android.dx.cf.code.RopperMachine.run(RopperMachine.java:291)
[apply]     at com.android.dx.cf.code.Simulator$SimVisitor.visitLocal(Simulator.java:608)
[apply]     at com.android.dx.cf.code.BytecodeArray.parseInstruction(BytecodeArray.java:526)
[apply]     at com.android.dx.cf.code.Simulator.simulate(Simulator.java:99)
[apply]     at com.android.dx.cf.code.Ropper.processBlock(Ropper.java:684)
[apply]     at com.android.dx.cf.code.Ropper.doit(Ropper.java:639)
[apply]     at com.android.dx.cf.code.Ropper.convert(Ropper.java:252)
[apply]     at com.android.dx.dex.cf.CfTranslator.processMethods(CfTranslator.java:252)
[apply]     at com.android.dx.dex.cf.CfTranslator.translate0(CfTranslator.java:131)
[apply]     at com.android.dx.dex.cf.CfTranslator.translate(CfTranslator.java:85)
[apply]     at com.android.dx.command.dexer.Main.processClass(Main.java:369)
[apply]     at com.android.dx.command.dexer.Main.processFileBytes(Main.java:346)
[apply]     at com.android.dx.command.dexer.Main.access$400(Main.java:59)
[apply]     at com.android.dx.command.dexer.Main$1.processFileBytes(Main.java:294)
[apply]     at com.android.dx.cf.direct.ClassPathOpener.processArchive(ClassPathOpener.java:244)
[apply]     at com.android.dx.cf.direct.ClassPathOpener.processOne(ClassPathOpener.java:130)
[apply]     at com.android.dx.cf.direct.ClassPathOpener.process(ClassPathOpener.java:108)
[apply]     at com.android.dx.command.dexer.Main.processOne(Main.java:313)
[apply]     at com.android.dx.command.dexer.Main.processAllFiles(Main.java:233)
[apply]     at com.android.dx.command.dexer.Main.run(Main.java:185)
[apply]     at com.android.dx.command.dexer.Main.main(Main.java:166)
[apply]     at com.android.dx.command.Main.main(Main.java:90)
[apply] ...at bytecode offset 00000006
[apply] locals[0000]: Lcom/officemax/impress/ui/library/task/DocumentBrowserTask;
[apply] locals[0001]: [Ljava/lang/Object;
[apply] locals[0002]: <invalid>
[apply] ...while working on block 0006
[apply] ...while working on method doTaskJob:([Ljava/lang/Object;)Lcom/kaciula/utils/ui/BasicTaskResponse;
[apply] ...while processing doTaskJob ([Ljava/lang/Object;)Lcom/kaciula/utils/ui/BasicTaskResponse;
[apply] ...while processing com/officemax/impress/ui/library/task/DocumentBrowserTask.class
[apply] 
[apply] 1 error; aborting

我怎样才能解决这个问题呢?

How can I fix this problem?

推荐答案

实际Proguard的部分完成,但DEX不能转换生成的字节code了。地塞米松认为 LocalVariableTable 不正确。埃里克Lafortune是更好的来源解释为什么(看他的答案)。

The actual Proguard part finishes, but then dex cannot convert the resulting bytecode anymore. Dex considers the LocalVariableTable incorrect. Eric Lafortune is the better source to explain why (see his answer).

的问题消失了,如果你不但不混淆,而且还跳过优化步骤( -dontoptimize )。但是,你想拥有这样的尺寸缩小。另一种方式来解决它砸在 javac的调试标志 DEX 。唯一的问题是,那么你就不会有适当的踪迹无论是。你会得到堆栈跟踪行没有源文件信息或行号,如:

The problem goes away if you not only don't obfuscate, but also skip the optimization step (-dontoptimize). But you want to have this for the size reduction. Another way to solve it is to drop the debug flags in javac and in dex. Only problem is that then you wouldn't have proper stacktraces either. You will get stacktrace lines without source file info or line numbers such as:

net.lp.collectionista.domain.items.book.BookItem.getCoverImageForFormField(Unkno‌​wn Source)

您可以通过添加做到这一点调试=假在蚂蚁<$ c中的的javac 标签$ C>主rules.xml中(您可能需要将部分复制到的build.xml 第一)。这将设置一个标志 javac的-g:无。您还可以配置DEX,这是很难做的,蚂蚁提供的模板。我复制了 DEX-帮手宏,确定它正在使用,并添加周围的地塞米松调用的条件标记:

You can do this by adding debug="false" in the javac tag in the ant main-rules.xml (you may want to copy the part to a build.xml first). This will set a flag javac -g:none. You also have to configure dex and this is harder to do in the provided ant template. I copied the dex-helper macro, made sure it was being used, and added a condition tag surrounding the dex calls:

        <echo>Converting compiled files and external libraries into ${intermediate.dex.file}...</echo>
        <if condition="debug">
            <then>
                <apply executable="${dx}" failonerror="true" parallel="true">
                    <arg value="--dex" />
                    <arg value="--output=${intermediate.dex.file}" />
                    <extra-parameters />
                    <arg line="${verbose.option}" />
                    <arg path="${out.dex.input.absolute.dir}" />
                    <path refid="out.dex.jar.input.ref" />
                    <external-libs />
                </apply>
            </then>
            <else>
                <apply executable="${dx}" failonerror="true" parallel="true">
                    <arg value="--dex" />
                    <arg value="--output=${intermediate.dex.file}" />
                    <arg value="--no-locals" /><!-- otherwise dex fails on the proguard bytecode -->
                    <extra-parameters />
                    <arg line="${verbose.option}" />
                    <arg path="${out.dex.input.absolute.dir}" />
                    <path refid="out.dex.jar.input.ref" />
                    <external-libs />
                </apply>
            </else>
        </if>

这是 - 没有当地人就这样办吧。

要减轻堆栈跟踪信息的丢失,您可以使用,分别为行号信息和类和方法名信息:

To mitigate the loss of stacktrace information you can use, respectively for line number information and class and method names information:

-keepattributes SourceFile, LineNumberTable
-keep,allowshrinking,allowoptimization class * { <methods>; }

这样,您就可以做局部模糊,而且还具有相当不错的踪迹。我还是建议你创建和释放后保持映射文件虽然。

This way you can do partial obfuscation, and still have equivalent good stacktraces. I still suggest you create and keep the mapping files upon release though.

在这一切,你不应该指定 -keepattributes LocalVariableTable,LocalVariableTypeTable ,同样 -keepparameternames 顶(如果你混淆,这本身可能让你陷入麻烦以及)。注意,第二意味着第一,即使它可能无法从它的名字清楚,它影响的属性。

On top of all this you shouldn't specify -keepattributes LocalVariableTable,LocalVariableTypeTable and equally -keepparameternames (if you do obfuscate, this by itself might get you into troubles as well). Note that the second implies the first, even though it may not be clear from its name that it affects attributes.

就个人而言,并考虑到其他问题Proguard的,我选择了做了模糊处理,但减少的堆栈跟踪信息的丢失。我没试过@农夫的建议呢。

Personally, and in view of other problems with Proguard, I chose to do the obfuscation but mitigate the loss of stacktrace information. I haven't tried @plowman's proposal yet.

有关详细信息,你可以找到我的版本控制的项目文件的位置:

For more details you can find my version controlled project files here:

  • <一个href="http://bazaar.launchpad.net/~pjv/collectionista/trunk/view/head:/collectionista/proguard.cfg">proguard.cfg

<一个href="http://bazaar.launchpad.net/~pjv/collectionista/trunk/view/head:/collectionista/build.xml">build.xml

这篇关于编译使用ProGuard给出例外:&QUOT;局部变量的类型不匹配&QUOT;的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆