AzoftБлогКак исправить ошибку VerifyError в Android-приложениях, использующих библиотеку Gson

Как исправить ошибку VerifyError в Android-приложениях, использующих библиотеку Gson

Алексей Васильков Июнь 4, 2013

Исправляем ошибку VerifyError в Android-приложениях, использующих библиотеку Gson

Одно из наших последних Android-приложений при падении возвращало довольно странную ошибку:

...

Caused by: java.lang.VerifyError: 

com.*.logic.ws.WebServiceHelper

...

Возникала ошибка всего у нескольких пользователей, но проигнорировать ее мы, конечно, не могли. Как оказалось, причина скрывалась в том, то некоторые производители телефонов — процент небольшой, но все же — включают библиотеку Gson в ОС устройства. В результате, при использовании данной библиотеки в приложении, возникал конфликт одинаковых классов в classpath

Если вы столкнулись с подобной проблемой или только начинаете разрабатывать приложение с использованием библиотеки Gson, мы рекомендуем пропатчить локальную версию библиотеки, задав уникальные пути для классов библиотеки, и ваше приложение будет стабильно работать на большем числе устройств. Но обо всем по порядку.

Поиск проблемы

Обычно причину подобной проблемы можно легко найти в логах LogCat, но сообщения об ошибке были получены с Google Play, поэтому в нашем распоряжении оказалась только малоинформативная трассировка стека, по которой можно было только понять, что ошибка java.lang.VerifyError произошла в неком классе, вызываемом из класса WebServiceHelper.

Обычно ошибка java.lang.VerifyError возникает, когда во время выполнения программы JVM понимает, что вызываемый метод на самом деле не существует или не совпадают сигнатуры вызываемого и реального методов. Например, вызов метода String.isEmpty() приведет к возникновению этой ошибки на устройствах с версией Android 2.2 и ниже, так как впервые этот метод был добавлен лишь в 9 версии API.

Поэтому перед выпуском приложения на рынок всегда необходимо тестировать его на минимальной поддерживаемой версии API, указанной в манифесте в атрибуте android:minSdkVersion. Кроме того, такие некорректные вызовы API легко находит Android Lint. Однако в нашем случае никаких некорректных вызовов Android API не было, да и сам класс WebServiceHelper был достаточно простым. Единственным местом, которое могло привести к подобной ошибке, была строка

return new Gson().fromJson(response, responseClass);

Решение

Изучив ресурсы по запросу «Android Gson VerifyError», мы выяснили, что на некоторых устройствах — в основном HTC — библиотека Gson уже присутствует в classpath, и, вместо того, чтобы использовать собственную библиотеку, приложение обращается к версии библиотеки, установленной на устройстве. Версии библиотек, конечно, не совпадают, что и приводит к ошибке. 

В одной из веток обсуждения был предложен вариант пропатчить локальную версию библиотеки, изменив название пакета с «com.google.gson» на «com.google.myjson», с помощью программы Jar Jar List. Им мы и воспользовались.

Итак, чтобы исправить ошибку, необходимо выполнить следующее:

  • Загрузить приложение Jar Jar List.
  • Поместить jarjar-1.3.jar и google-gson-1.6.jar в одну папку.
  • Создать в этой папке новый текстовый файл rules.txt.
  • Записать в него следующую строку rule com.google.gson.** com.google.myjson.@1.
  • Из командной строки запустить команду «java -jar jarjar-1.3.jar process rules.txt google-gson-1.6.jar google-gson-1.6-patched.jar».
  • Заменить старую Gson-библиотеку на новую и поправить все импорты в классах.

Описанным методом мы рекомендуем воспользоваться тем, кто, разрабатывая Android-приложения, использует библиотеку Gson — приложение будет работать более стабильно. Проверено.

Комментарии

комментарии



Content created by Alex Vasilkov