Compiler avec Proguard donne SimException: “variable locale”incompatibilité de type
Quand je compile mon Application Android avec Proguard activé j'obtiens l'erreur suivante:
-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
Comment puis-je résoudre ce problème?
- J'ai signalé ce parce que je sentais que c'était la meilleure chose à faire, plutôt que d'ignorer les déjà silencieux problème: sourceforge.net/tracker/...
- S'il vous plaît laissez-moi savoir quand vous avez trouvé une solution à cela. J'ai vraiment besoin de rétrécir mes applications car j'utilise beaucoup de bibliothèques.
- J'ai fermé le bug. Je pense que nous avons à vivre avec les solutions de contournement.
Vous devez vous connecter pour publier un commentaire.
Le réel Proguard partie se termine, mais alors dex ne peut pas convertir l'résultant du bytecode plus. Dex considère la
LocalVariableTable
incorrect. Eric Lafortune est la meilleure source pour expliquer pourquoi (voir sa réponse).Le problème disparaît si vous n'avez pas seulement ne pas obscurcir, mais également ignorer de l'optimisation de l'étape (
-dontoptimize
). Mais vous voulez avoir ce pour la réduction de la taille. Une autre façon de le résoudre est de faire tomber les indicateurs de débogage dansjavac
et dansdex
. Seul problème, c'est qu'alors vous ne serait pas bon stacktraces soit. Vous obtiendrez stacktrace lignes sans fichier source de l'info ou des numéros de ligne, telles que:Vous pouvez le faire en ajoutant
debug="false"
dans lejavac
tag de la fourmimain-rules.xml
(vous pouvez copier la partie à unbuild.xml
premier). Cela permettra de définir un indicateurjavac -g:none
. Vous devez également configurer dex et c'est plus difficile à faire dans la condition ant modèle. J'ai copié ledex-helper
macro, fait en sorte qu'il a été utilisé, et ajout d'une condition de balises entourant l'indice dex des appels:C'est le
--no-locals
qui le fait.Pour atténuer la perte de stacktrace informations que vous pouvez utiliser, respectivement, pour le numéro de ligne et de la classe et de la méthode des noms d'informations:
De cette façon, vous pouvez partielle de dissimulation, et encore avoir l'équivalent d'une bonne stacktraces. J'ai toujours penser vous de créer et de garder les fichiers de mappage lors de la libération de bien.
Sur le dessus de tout cela, vous ne devriez pas spécifier
-keepattributes LocalVariableTable,LocalVariableTypeTable
et également-keepparameternames
(si vous ne obscurcir, cela, en soi, pourrait vous amener des ennuis ainsi). Notez que la seconde implique la première, même si elle peut ne pas être clair à partir de son nom qu'elle affecte les attributs.Personnellement, et en raison d'autres problèmes avec Proguard, j'ai choisi de faire de la dissimulation, mais d'atténuer la perte de stacktrace de l'information. Je n'ai pas essayé @plowman la proposition de encore.
Pour plus de détails, vous pouvez trouver mon projet sous contrôle de version des fichiers ici:
proguard.cfg
build.xml
project.tasks.withType(com.android.build.gradle.tasks.Dex) { additionalParameters=['--no-locals'] }
buildTypes { release {
bloc dans le module de génération.gradle. Merci Johan!J'ai rencontré le même problème après l'ajout de l'-dontobfuscate drapeau pour ma proguard.fichier cfg.
La solution a fini par être que j'avais besoin de l'ajouter à mon optimisations:
Cela rend mon complet d'optimisation de la chaîne ressembler à ceci:
-dontobfuscate
mais était d'avoir des erreurs, et en faisant seulement ce changement a résolu le problème pour moi. Merci!!code/allocation/variable
pour les optimisations de correction de l'erreur.minifyEnabled false
!code/allocation/variable
, il fonctionne ok!C'est un bug dans ProGuard. Son optimisation de l'étape n'a parfois pas de mise à jour de l'option "LocalVariableTable" et "LocalVariableTypeTable" debug attributs à l'intérieur des fichiers de classe entièrement correctement. Le Dalvik VM explicitement vérifie le débogage des attributs et rejette les fichiers de classe si elles sont incompatibles.
Vous devriez vérifier si la dernière version de ProGuard résout le problème. Sinon, vous devez supprimer locale des noms de variables et des types de fichiers de classe. Vous pouvez demander au compilateur java ne pas générer (par exemple, "javac -g:none"). Vous pouvez également demander ProGuard de ne pas les garder (ne pas spécifier "-keepattributes LocalVariableTable,LocalVariableTypeTable").
!code/allocation/variable
, a résolu le problèmeJ'ai juste eu cette refont surface sur Windows Android Studio, et la désactivation Instantanée rendu les choses fonctionnent à nouveau.