2013-04-03 18 views
5

Ho un'applicazione basata su Android che si collega a Google App Engine utilizzando i servizi di Rest, l'app funziona perfettamente finché non viene offuscata tramite ProGuard prima del rilascio.ProGuard - org.codehaus.jackson.map.JsonMappingException: Nessun costruttore adatto trovato per il tipo

L'errore riportato nel LogCat quando si esegue l'applicazione offuscato è:

Unable to convert a [application/json,UTF-8] representation into an object of 
    class com.enterprisemk.android.bcw.bincollection.WasteCollectionAreasContainer 

org.codehaus.jackson.map.JsonMappingException: No suitable constructor found 
    for type [simple type, class 
    com.enterprisemk.android.bcw.bincollection.WasteCollectionAreasContainer]: 
    can not instantiate from JSON object (need to add/enable type information?) 

Ho il seguente nel mio Proguard-project.txt di file:

-keepattributes *Annotation*,EnclosingMethod 

-keep public class org.w3c.** {public private protected *;} 
-dontwarn org.w3c.** 

-keep public class org.joda.time.** {public private protected *;} 
-dontwarn org.joda.time.** 

-keep public class org.restlet.** { *; } 
-dontwarn org.restlet.** 

-keep public class org.codehaus.** { *; } 
-dontwarn org.codehaus.** 

-keepattributes Signature 
-keepnames class com.fasterxml.jackson.** { *; } 
-dontwarn com.fasterxml.jackson.databind.** 

E la mia classe l'errore si riferisce a assomiglia a:

Per reiterare prima di offuscare tramite ProGuard, l'app funziona perfettamente.
Qualcuno può aiutarmi a risolvere questo problema?

+0

po 'di tempo progaurd rimuove alcune classi dal percorso di generazione di progetti appositamente biblioteca. – Ankit

+0

Suona come Proguard può aver rimosso il default, costruttore senza parametri per 'WasteCollectionAreasContainer'. Anche questa classe ha un costruttore sovraccarico? Potrebbe essere Proguard è spogliando il costruttore di default * perché * v'è un sovraccarico * e * si pensa che il costruttore di default non viene utilizzato ovunque - che può accadere a causa Proguard non può rilevare che Jackson in realtà usa/richiede un costruttori di default per POJO in fase di esecuzione. –

+0

MH - questo mi partì nella giusta direzione per fissare il problema - grazie –

risposta

1

Il messaggio di errore

org.codehaus.jackson.map.JsonMappingException: No suitable constructor found for type 
    [simple type, class com.enterprisemk.android.bcw.bincollection.WasteCollectionAreasContainer]: 
    can not instantiate from JSON object (need to add/enable type information?) 

suggerisce che la biblioteca Jackson sta cercando di deserializzare la classe utilizzando la riflessione, con il suo nome originale e il suo costruttore annotato. ProGuard non può prevederlo, quindi potrebbe aver rimosso o rinominato la classe e il suo costruttore. È probabile che sia necessario a garantirne la conservazione in modo esplicito:

-keep class com.enterprisemk.android.bcw.bincollection.WasteCollectionAreasContainer { 
    <init>(java.util.List); 
} 

Ci possono essere altre classi/campi/metodi simili che devono essere conservati per le stesse ragioni.

+0

Eric - essenzialmente, questo è quello che ho fatto. E avevi ragione, avevo altre classi/campi/metodi che dovevano essere conservati allo stesso modo. Grazie per la risposta positiva. –

2

Aggiungere il seguente al vostro Proguard.config. Ti aiuterà a localizzare il problema.

-verbose 
-dump class_files.txt 
-printseeds seeds.txt 
-printusage unused.txt 
-printmapping mapping.txt 

Ho il seguente nel mio Proguard-project.txt file di

Credo che si dovrebbe utilizzare proguard-android-optimize.txt, e non proguard-android.txt.

Per completezza, grazie Riley Hassell sulla Android Security Discussions per i trucchi.

+1

The Ant/Eclipse principio muove già contengono le opzioni -print; dovresti trovare i file risultanti nella directory bin/proguard.La fase di ottimizzazione di ProGuard elabora ulteriormente il codice; generalmente non risolve alcun problema di configurazione. Tuttavia, è raccomandato per i migliori risultati. –

1

Una soluzione migliore, nel caso in cui qualcun altro ha questo problema, è la seguente:

# keep anything annotated with @JsonCreator 
-keepclassmembers public class * { 
    @com.fasterxml.jackson.annotation.JsonCreator *; 
} 

che mantiene qualsiasi metodo annotato con JsonCreator, che è probabilmente voleva fare in questo caso. Se hai bisogno di caricare più classi, puoi evitare di dover specificare ogni classe individualmente.

Problemi correlati