XStream создает исключение «конструктор без аргументов» на Android - PullRequest
3 голосов
/ 08 сентября 2011

Я пытаюсь использовать XStream для (де) сериализации HashMap некоторых из моих собственных классов в приложении для Android. Например, одним из классов является Word, который имеет следующие переменные:

private String word;
private boolean capitalizable;
private int useCount;
private HashMap<Character,Integer> endPunctuation;
private HashSet<String> nextWritables;

У меня уже есть все настройки, работающие в стандартном Java-приложении, я просто пытаюсь обернуть все это в пользовательский интерфейс Android (который работает отлично). Сериализация прекрасно работает в Android. Проблема, с которой я столкнулся, заключается в том, что при десериализации я получаю следующую ошибку:

com.thoughtworks.xstream.converters.ConversionException: Cannot construct chatai.Word as it does not have a no-args constructor : Cannot construct chatai.Word as it does not have a no-args constructor 
---- Debugging information ---- 
message             : Cannot construct chatai.Word as it does not have a no-args constructor 
cause-exception     : com.thoughtworks.xstream.converters.reflection.ObjectAccessException 
cause-message       : Cannot construct chatai.Word as it does not have a no-args constructor 
class               : java.util.HashMap 
required-type       : chatai.Word 
path                : /map/entry/chatai.Word 
line number         : 1 
------------------------------- 

Я получаю эту ошибку, если я использую любую версию XStream, кроме 1.4.1, в своем настольном приложении. Я всегда получаю сообщение об ошибке в приложении для Android, независимо от версии XStream. Я уверен, что у настольного компьютера есть эта проблема, потому что он работает на Java 7. Я не уверен насчет Android. Это как-то связано с отражением из-за этого предупреждения при добавлении xstream-1.4.1.jar:

[2011-09-07 21:06:52 - DroidBot] Dx warning: Ignoring InnerClasses attribute for an anonymous inner class 
(com.thoughtworks.xstream.XStream$2) that doesn't come with an 
associated EnclosingMethod attribute. This class was probably produced by a 
compiler that did not target the modern .class file format. The recommended 
solution is to recompile the class from source, using an up-to-date compiler 
and without specifying any "-target" type options. The consequence of ignoring 
this warning is that reflective operations on this class will incorrectly 
indicate that it is *not* an inner class. 

Быстрый тест показывает, что сериализация и десериализация объекта String в Android работает нормально. Как я могу избавиться от этой ошибки?

1 Ответ

2 голосов
/ 10 января 2014

Да, этот вопрос старый, но для любопытного интернет-исследователя:

Для десериализации требуется xstream, чтобы создать объект и установить для всех его полей-членов значения, указанные в xml.Если объект, который вы пытаетесь десериализовать, не имеет конструктора без аргументов, тогда xstream требуется помощь от виртуальной машины для создания объекта вне обычного процесса создания и инициализации объекта.Эта помощь доступна только в определенных виртуальных машинах;он недоступен в виртуальной машине Dalvik при работе на устройстве Android.

Если вы проверите провайдера, который используется для десериализации вашего xml, вы обнаружите, что на вашем рабочем столе провайдер, вероятно, Sun14ReflectionProvider, которыйиспользует специальную поддержку VM для создания объектов без вызова их конструкторов.Под Android провайдером будет PureJavaReflectionProvider, который не может десериализовать объекты без конструктора без аргументов.

    XStream xstream = new XStream();

    ReflectionProvider rp = xstream.getReflectionProvider();
    if(null != rp)
    {
        System.out.println("Provider class: " + rp.getClass().getName());
        if(rp instanceof Sun14ReflectionProvider)
            System.out.println("Using Sun14ReflectionProvider");
        else if(rp instanceof PureJavaReflectionProvider)
            System.out.println("Using PureJavaReflectionProvider");
    }

В заключение: вы не можете десериализовать объект без конструктора без аргументов при запуске XStream в среде Android,Если у вас есть контроль над объектом, сделайте рефакторинг, чтобы получить конструктор без аргументов.Если у вас нет контроля над объектом, вам не повезло в том, что касается XStream.

...