2013-04-18 2 views
7

Есть ли явный способ остановить ProGuard от изменения класса от реализации интерфейса?Как остановить ProGuard от удаления интерфейса Serializable от класса

У меня есть класс, который реализует 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 s, поэтому мне нужно Serializable. Я считал, что, возможно, каким-то образом ProGuard считает, что Foo никогда не используется как Serializable, но это кажется маловероятным, учитывая, что я передаю его как параметр Bundle.putSerializable(String, Serializable), а также я делаю неявный листинг: Serializable serializable = foo;. На самом деле, когда я отлаживаю, я вижу, что Foo попал в Bundle, и я могу проверить Bundle и увидеть экземпляр Foo там, но при его получении сбрасывается.

ответ

4

ProGuard никогда не разделяет интерфейсы, определенные в библиотеках (например, Serializable) из классов в обработанном коде (например, Foo). Код библиотеки может быть передан этим интерфейсам, поэтому их нельзя удалить.

Я получаю нулевой после того как я отлит из Сериализуемых к Foo

Это означает, что экземпляр должен быть пустым, чтобы начать с. Ваш анализ будет правильным, если вы получите ClassCastException. Вы можете проверить, что Foo по-прежнему реализует Serializable с помощью javap. Проблема, вероятно, лежит где-то в другом месте. Для получения советов по сериализации вы можете посмотреть руководство ProGuard> Примеры>Processing serializable classes.

Update:

В этом случае оказывается проблема конфигурации. ProGuard может обрабатывать только файлы классов, если он знает все об их иерархии (подобно компилятору).Вы действительно должны указать классы среды выполнения:

-libraryjars <java.home>/lib/rt.jar 

или для Android:

-libraryjars /usr/local/android-sdk/platforms/android-17/android.jar 

Андроида Ant/Eclipse, сборках автоматически задать все необходимые -injars/-outjars/-libraryjars варианты для вас, но в процессе пользовательской сборки вы должны сами указать их. ЧФР. Руководство ProGuard> Примеры>A complete Android application.

Обратите внимание, что опция -dontwarn предупреждает об уходе, но не проблемы. Используйте его, если это действительно необходимо.

+0

Спасибо за вход, но я проверил с '' javap' и Foo' не реализует 'Serializable' больше. Ваш комментарий о 'ClassCastException' имеет смысл для меня тоже, но он просто не работает так. Мое подозрение в том, что что-то произошло в сокращении и оптимизации, чтобы изменить поведение от того, что можно ожидать от нормального Java-кода, поскольку на тот момент это уже не Java, а байт-код. – kabuko

+0

Я обнаружил, что если у меня ProGuard установлен '-dontshrink', а затем явным образом использую' -keep, allowoptimization, allowhrinking, allowobfuscation Foo', то 'Foo' будет по-прежнему реализовывать' Serializable', но, к сожалению, это не решение для меня так как я хотел бы свернуть, чтобы быть в целом. – kabuko

+0

Если у вас есть небольшой образец, который иллюстрирует проблему, я рассмотрю ее. Вы можете найти мой адрес электронной почты на странице «Обратная связь» веб-сайта ProGuard. –

21

У меня была такая же проблема, как описано ниже.

-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#serializable

+2

Документация: http://proguard.sourceforge.net/manual/examples.html#serializable – shkschneider

+1

На мой взгляд, это должно было быть стандартом по умолчанию в proguard. – nilsmagnus

+0

Спасибо! Я потратил столько времени, пытаясь заставить это работать. – Eduard

Смежные вопросы