stürzt mit NoSuchMethodError ab, nachdem mit Methodenreferenzen fortgefahren wurde

8

der Quellcode vor dem Kompilieren und Progard:

%Vor%

der dekompilierte Code nach dem Kompilieren und Progardieren: (Dekompiliert mit CFR 0_118)

%Vor%

ist jetzt der Schlüsselcode nach compile & amp; progard, dem dekompilierten Code der b -Klasse:

%Vor%

bezog sich immer noch auf die Methode finish() , die bereits von prouard als m() verschleiert wurde.

Ich erwarte, dass die referenz finish () -Methode als m () verschleiert wird, aber das passiert nicht, und das ist meine Frage.

Proguard hat mich nicht gewarnt, es stürzt nur mit NoSuchMethodError auf der Laufzeit ab, sobald es den falschen Code trifft. Also sag mir nicht, dass ich eine Proguard-Konfiguration wie -dontwarn java.lang.invoke. * hinzufügen soll, die ich ausprobiert habe, aber es hat nicht funktioniert.

Vielleicht war die Bearbeitungsreihenfolge der beteiligten Klassen während der Verschleierung falsch, wer weiß?

Ich möchte die Annotation @Keep nicht in die finish () -Methode einfügen, es ist eine schlechte Lösung und ich müsste mich darum kümmern und Methodenreferenzen in Zukunft sorgfältig verwenden, also suche ich nach der beste Lösung.

unten sind meine Standardkonfigurationen:

%Vor%

Unten ist mein proguard-rules.pro :

%Vor%     
VinceStyling 11.05.2017, 13:26
quelle

4 Antworten

0

Nach einer nochmaligen Überprüfung, habe ich festgestellt, dass es sich wahrscheinlich nicht um einen Programmfehler handelt, sondern nur um Großbuchstaben.

Zuerst lasse ich den Quellcode unter Verwendung des allgemeinen Schnittstellencodierungsstils:

%Vor%

Dann reinige ich den Build-Cache und rebuild:

%Vor%

Ich führe die Ausgabeversions-App aus und lasse sie den problematischen Code erreichen, der ohne Absturz funktioniert.

Dieses Mal wende ich mich Methodenreferenzen zu:

%Vor%

aber ich habe den Build-Cache vor dem erneuten Aufbau nicht bereinigt:

%Vor%

jetzt wieder mit dem Absturz passieren geschehen:

%Vor%

um zu bestätigen, dass es sich um den Build-Cache-Grund handelt, baue ich den grundlegend auf den geänderten Code zurück:

%Vor%

Dieser Absturz ist in der Nachwort-App verschwunden.

Ich versuche, ein Demonstrationsprojekt zu erstellen, um dieses Problem zu beweisen, aber das Projekt stürzt den Absturz nur in meinem produktiven Projekt ab.

    
VinceStyling 22.05.2017, 06:53
quelle
2

Das Durcharbeiten dieser Fehler, die -keep nicht beheben kann, ist ein REAL Schmerz und der einzige Weg, auf dem ich je Fortschritte gemacht habe, ist die folgende Strategie:

  1. Finde heraus, in welcher Phase des Proguard-Zyklus der Bug eingeführt wird (Schrumpfen, Optimieren oder Verschleiern)
  2. Fügen Sie Ausnahmen für diesen Schritt hinzu oder entfernen Sie sie, indem Sie vom breitesten Bereich des Ausschlusses zum schmalsten übergehen, bis das Problem wieder auftaucht

E.G.

Stellen Sie sicher, dass dies ein Optimierungsproblem ist oder nicht

  1. Fügen Sie -dontoptimize anstelle von -optimizations string rebuild und test
  2. hinzu
  3. Wenn der Absturz gemildert wird, durchlaufen Sie die Klassen der Optimierungsausschlüsse auf der höchsten Ebene !method/*, !code/*, !class/*, !field/* , bis Sie feststellen, durch welchen Ausschluss das Problem behoben wird
  4. Bestimmen Sie, was der minimale Ausschluss in dieser Ausschlussklasse ist (vorausgesetzt, es war !method/* , gehen Sie von !method/marking/* und wenn das auch funktioniert, versuchen Sie !method/marking/final . Wenn das funktioniert, dann haben Sie die gefunden minimaler Ausschluss)

Dies könnte sehr wohl ein Fehler in den Proguard Regeln einer der verwendeten Bibliotheken sein oder in der Version von Proguard, die Sie selbst verwenden (I hab beide gesehen also versuche beide auch zu aktualisieren.

    
quelle
0

Die Webseite / github Ihrer Bibliothek bietet meistens die notwendigen Regeln für die Progardierung wie retrolamda :

%Vor%

Proguarding ist eine Trail-Error-Geschichte. Überprüfen Sie Ihre Protokollierung, um festzustellen, welche Bibliothek, Klasse oder Komponente ein Problem verursacht, und fügen Sie sie sorgfältig zu den Regeln hinzu:).

Ihr Fehler NoSuchMethod speziell:

  

Ihr Code ruft wahrscheinlich etwas wie myClass.getMethod auf und versucht es   um eine Methode dynamisch zu finden. Da ProGuard nicht immer erkennen kann   Dies müssen Sie automatisch die fehlende Methode bei der Verwendung der   geeignete Option -keep:

     

-keepclassmembers-Klasse mypackage.MyClass {void myMethod (); }

    
DroidBender 15.05.2017 07:49
quelle
0

Dies geschieht, wenn eine Klasse nach einer Methode eines gegebenen Arguments sucht oder sie direkt über die Reflektion zur Laufzeit aufruft. Proguard kann Sie dazu nicht warnen, da in der Kompilierzeit keine Verbindung zwischen der verschleierten Klasse und der Verbraucherklasse besteht. Du kannst etwas wie

haben %Vor%

Da die Methode referenziert wird, wird eine Zeichenkette mit dem Namen verwendet, proguard erkennt sie nicht und in der Laufzeit kommt es zu einem Absturz. Die einzige Lösung ist, vorausgesetzt, Sie können den Code nicht ändern, ist es, die Methode und Klasse zu verschleiern.

(Sie können ein realistischeres Beispiel in Ormlite-Android überprüfen)

    
Fco P. 22.05.2017 06:52
quelle