是否有明确的方法可以阻止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)
并且我做了隐式演员:{ {1}}。事实上,当我调试时,我可以看到Serializable serializable = foo;
被放入Foo
,我可以检查Bundle
并查看Bundle
的实例,但是在检索时演员失败了。
答案 0 :(得分:28)
我使用下面的配置修复了相同的问题。
-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
答案 1 :(得分:4)
ProGuard永远不会从库中定义的接口(如Serializable)中删除处理代码中的类(如Foo)。库代码可能会转换为这些接口,因此无法将其删除。
从Serializable转换为Foo后,我得到null
这意味着实例必须为null才能开始。如果你得到ClassCastException,你的分析是正确的。您可以检查Foo是否仍然使用javap
实现Serializable。问题可能在于其他地方。有关序列化的提示,您可以查看ProGuard手册&gt;例子&gt; 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手册&gt;例子&gt; A complete Android application
请注意,-dontwarn选项会使警告消失,但不会出现问题。只有在必要时才使用它。