Как остановить 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

Другие вопросы по тегам