У меня есть Android-приложение, которое подключается к Google App Engine с помощью служб Rest, приложение отлично работает, пока оно не запутано через ProGuard до выпуска.
Ошибка, зарегистрированная в LogCat при запуске запущенного приложения:
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?)
В моем файле proguard-project.txt есть следующее:
-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.**
И мой класс, к которому относится ошибка, выглядит так:
public class WasteCollectionAreasContainer { public List<WasteCollectionAreas> wasteCollectionAreasList; public List<WasteCollectionAreas> getWasteCollectionAreasList() { return wasteCollectionAreasList; } public void setWasteCollectionAreasist(List<WasteCollectionAreas> wasteCollectionAreasList) { this.wasteCollectionAreasList = wasteCollectionAreasList; } public WasteCollectionAreasContainer() { wasteCollectionAreasList = new ArrayList<WasteCollectionAreas>(); } @JsonCreator public WasteCollectionAreasContainer(List<WasteCollectionAreas> wasteCollectionAreasList) { this.wasteCollectionAreasList = wasteCollectionAreasList; } }
Чтобы повторить до обфускации через ProGuard, приложение работает отлично.
Может ли кто-нибудь помочь мне решить эту проблему?
Сообщение об ошибке
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?)
Предполагает, что библиотека Джексона пытается десериализировать ваш класс с использованием отражения, с его оригинальным именем и его аннотированным конструктором. ProGuard не может этого предвидеть, поэтому он может удалить или переименовать класс и его конструктор. Вам, вероятно, необходимо их явно сохранить:
-keep class com.enterprisemk.android.bcw.bincollection.WasteCollectionAreasContainer { <init>(java.util.List); }
Могут быть другие аналогичные классы / поля / методы, которые необходимо сохранить по тем же причинам.
Добавьте в свой Proguard.config
. Это поможет вам найти проблему.
-verbose -dump class_files.txt -printseeds seeds.txt -printusage unused.txt -printmapping mapping.txt
В моем файле proguard-project.txt есть следующее:
Я считаю, что вы должны использовать proguard-android-optimize.txt
, а не proguard-android.txt
.
Для полноты, спасибо Райли Хасселлу за обсуждения Android Security для трюков.
Лучшее решение, если у кого-либо еще есть эта проблема, заключается в следующем:
# keep anything annotated with @JsonCreator -keepclassmembers public class * { @com.fasterxml.jackson.annotation.JsonCreator *; }
Это поддерживает любой метод, аннотированный JsonCreator, который, вероятно, хотел бы сделать в этом случае. Если у вас есть несколько классов, которые необходимо загрузить, вы можете не указывать каждый класс отдельно.