Как остановить ProGuard от удаления интерфейса Serializable из класса
Есть ли явный способ помешать ProGuard изменить класс от реализации интерфейса?
У меня есть класс, который реализует java.io.Serializable
давайте назовем это com.my.package.name.Foo
, Я обнаружил, что после запуска через ProGuard, он больше не реализует Serializable
, я получил null
после того, как я бросил из Serializable
в Foo
а также false
если я проверю экземпляр с instanceof Serializable
, Я удостоверился, чтобы ProGuard игнорировал этот класс:
-keep class com.my.package.name.Foo
Я также попробовал:
-keep class com.my.package.name.Foo { *; }
и я также попробовал весь пакет, выполнив это:
-keep class com.my.package.name.** { *; }
или же:
-keep class com.my.package.** { *; }
а также просто сохранить все Serializable
классы:
-keep class * implements java.io.Serializable { *; }
но безрезультатно. У меня есть другой класс в пакете родного брата (примерно: com.my.package.name2.Bar
) который также реализует Serializable
и используется аналогично, но не имеет проблем.
Я не уверен, что это актуально, но я упаковываю это в банку для использования с Android. Код, который использует эти классы, включает их Bundle
с, поэтому мне нужно Serializable
, Я считал, что, возможно, каким-то образом ProGuard считает, что Foo
никогда не используется как Serializable
но это кажется маловероятным, учитывая, что я передаю его в качестве параметра Bundle.putSerializable(String, Serializable)
а также я делаю неявное приведение: Serializable serializable = foo;
, На самом деле, когда я отлаживаю, я вижу Foo
попасть в Bundle
и я могу изучить Bundle
и увидеть пример Foo
там, но при получении его приведение не удается.
2 ответа
ProGuard никогда не удаляет интерфейсы, которые определены в библиотеках (например, Serializable), из классов в коде, который обрабатывается (например, Foo). Библиотечный код может быть приведен к этим интерфейсам, поэтому их нельзя удалить.
Я получаю ноль после того, как я брошу из Сериализуемого в Foo
Это означает, что экземпляр должен быть нулевым для начала. Ваш анализ будет правильным, если вы получите ClassCastException. Вы можете проверить, что Foo все еще реализует Сериализуемый с javap
, Проблема, вероятно, лежит в другом месте. Советы по сериализации вы можете найти в руководстве ProGuard> Примеры> Обработка сериализуемых классов.
Обновить:
В этом случае оказывается проблема конфигурации. ProGuard может обрабатывать файлы классов, только если он знает все об их иерархии (точно так же как компилятор). Вы действительно должны указать классы времени выполнения:
-libraryjars <java.home>/lib/rt.jar
или для Android:
-libraryjars /usr/local/android-sdk/platforms/android-17/android.jar
В сборках Android Ant/Eclipse автоматически указываются все необходимые параметры -injars/-outjars/-libraryjars, но в процессе пользовательской сборки вы должны указать их самостоятельно. ЧФР. Руководство по ProGuard> Примеры> Полное приложение для Android.
Обратите внимание, что опция -dontwarn устраняет предупреждения, но не проблемы. Используйте только если это действительно необходимо.
У меня была та же проблема, исправленная с помощью приведенного ниже конфига.
-keepnames class * implements java.io.Serializable
-keepclassmembers class * implements java.io.Serializable {
static final long serialVersionUID;
private static final java.io.ObjectStreamField[] serialPersistentFields;
!static !transient <fields>;
private void writeObject(java.io.ObjectOutputStream);
private void readObject(java.io.ObjectInputStream);
java.lang.Object writeReplace();
java.lang.Object readResolve();
}
Официальная документация http://proguard.sourceforge.net/manual/examples.html