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



是否有明确的方法来阻止ProGuard从实现接口更改类?

我有一个实现java.io.Serializable的类,我们称它为com.my.package.name.Foo。我发现,通过ProGuard运行后,它不再实现Serializable。如果我检查instanceof Serializable的实例,我从SerializableFoofalse转换后得到null。我已经将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的实例,但是在检索它时,强制转换失败。

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

-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可序列化的

ProGuard不会从处理的代码(如Foo)中的类中剥离在库中定义的接口(如Serializable)。标准库代码可能会强制转换到这些接口,因此它们不能被删除。

我从Serializable转换为Foo后得到null

这意味着该实例必须为空以开始。如果您得到ClassCastException,您的分析将是正确的。您可以检查Foo仍然使用javap实现Serializable。问题可能出在其他地方。有关序列化的提示,您可以查看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应用程序。

注意- donwarn选项会使警告消失,但不会使问题消失。

相关内容

  • 没有找到相关文章

最新更新