2013-04-03 1 views
5

У меня есть приложение на базе Android, которое подключается к Google App Engine с помощью служб Rest, приложение отлично работает, пока оно не запутано через ProGuard до выпуска.ProGuard - org.codehaus.jackson.map.JsonMappingException: Не найдено подходящего конструктора для типа

Ошибка сообщается в 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, приложение работает отлично.
Может ли кто-нибудь помочь мне решить эту проблему?

+0

некоторое время progaurd удаляет некоторые классы из пути сборки специально для проектов библиотеки. – Ankit

+0

Похоже, что Proguard, возможно, удалил непараметрированный конструктор по умолчанию для 'WasteCollectionAreasContainer'. У этого класса тоже есть перегруженный конструктор? Это может быть Proguard лишает конструктор по умолчанию *, потому что * есть перегрузка * и * он думает, что конструктор по умолчанию нигде не используется - это может произойти, потому что Proguard не может обнаружить, что Джексон фактически использует/требует конструкторы по умолчанию для POJO во время выполнения. –

+0

MH - это поставило меня в правильном направлении, чтобы исправить проблему - спасибо –

ответ

1

Сообщение об ошибке

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); 
} 

Там могут быть и другие подобные классы/поля/методы, которые должны быть сохранены по тем же причинам.

+0

Eric - в высшей степени, это то, что я сделал. И вы были правы, у меня были другие классы/поля/методы, которые необходимо сохранить аналогичным образом. Спасибо за ответный ответ. –

2

Добавить следующее в ваш 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 Discussions за трюки.

+1

Стандартные сборки Ant/Eclipse уже содержат параметры -print; вы должны найти результирующие файлы в каталоге bin/proguard.Шаг оптимизации ProGuard обрабатывает код еще немного; он вообще не решает никаких проблем с конфигурацией. Тем не менее, рекомендуется для достижения наилучших результатов. –

1

Лучшее решение, в случае, если кто-то есть эта проблема, заключается в следующем:

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

Это держит любой метод с аннотацией JsonCreator, который, вероятно, хотел сделать в этом случае. Если у вас есть несколько классов, которые необходимо загрузить, вы можете не указывать каждый класс отдельно.