如何阻止ProGuard从类中剥离Serializable接口

问题描述 投票:9回答:2

是否有一种明确的方法可以阻止ProGuard将类更改为实现接口?

我有一个实现java.io.Serializable的类,我们称之为com.my.package.name.Foo。我发现在运行ProGuard后,它不再实现Serializable。我从null投射到SerializableFoo后,如果我用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。使用这些类的代码包括将它们放在Bundles中,这就是我需要Serializable的原因。我认为也许不知何故,ProGuard认为Foo从未被用作Serializable,但这似乎不太可能,因为我将它作为参数传递给Bundle.putSerializable(String, Serializable),而且我做了一个隐含的演员:Serializable serializable = foo;。事实上,当我调试时,我可以看到Foo被放入Bundle并且我可以检查Bundle并在那里看到Foo的实例,但是当检索它时,强制转换失败。

java android proguard serializable
2个回答
4
投票

ProGuard永远不会从库中定义的接口(如Serializable)中删除已处理的代码中的类(如Foo)。库代码可能会转换为这些接口,因此无法删除它们。

从Serializable转换为Foo后,我得到null

这意味着实例必须为null才能开始。如果你得到ClassCastException,你的分析是正确的。您可以检查Foo是否仍然使用javap实现Serializable。问题可能在于其他地方。有关序列化的提示,您可以查看ProGuard手册>示例> Processing serializable classes

更新:

在这种情况下,结果是配置问题。如果ProGuard知道关于其层次结构的所有内容(就像编译器一样),它只能处理类文件。你真的必须指定运行时类:

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

或者对于Android:

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

Android Ant / Eclipse构建会自动为您指定所有必需的-injars / -outjars / -libraryjars选项,但在自定义构建过程中,您必须自己指定它们。 (CFR)。 ProGuard手册>示例> A complete Android application

请注意,选项-dontwarn会使警告消失,但不会出现问题。只有在必要时才使用它。


26
投票

我使用下面的配置修复了同样的问题。

-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

© www.soinside.com 2019 - 2024. All rights reserved.