如何阻止ProGuard从类中剥离Serializable接口 [英] How to stop ProGuard from stripping the Serializable interface from a class

查看:114
本文介绍了如何阻止ProGuard从类中剥离Serializable接口的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Is there an explicit way to stop ProGuard from changing a class from implementing an interface?

我有一个实现java.io.Serializable的类,我们称它为com.my.package.name.Foo.我发现通过ProGuard运行后,它不再实现Serializable.如果我使用instanceof Serializable检查实例,则从Serializable投射到Foofalse后,会得到null.我已经确保将ProGuard设置为忽略此类:

I have a class that implements java.io.Serializable, let's call it com.my.package.name.Foo. I've found that after running through ProGuard, it no longer implements Serializable. I get null after I cast from Serializable to Foo and false if I check an instance with instanceof Serializable. I've made sure to set ProGuard to ignore this class:

-keep class com.my.package.name.Foo

我也尝试过:

-keep class com.my.package.name.Foo { *; }

我还通过以下方法尝试了整个软件包:

and I've also tried the whole package by doing this:

-keep class com.my.package.name.** { *; }

或:

-keep class com.my.package.** { *; }

并保留所有Serializable类:

-keep class * implements java.io.Serializable { *; }

但无济于事.我在同级程序包中有另一个类(大致为:com.my.package.name2.Bar),该程序包也实现了Serializable,用法类似,但没有问题.

but to no avail. I have another class in a sibling package (roughly: com.my.package.name2.Bar) that also implements Serializable and is used similarly but has no issues.

我不确定是否相关,但我将其包装在一个罐子中以供Android使用.使用这些类的代码包括将它们放在Bundle中,这就是为什么我需要Serializable的原因.我认为ProGuard可能以某种方式认为Foo从未用作Serializable,但是考虑到我将其作为参数传递给Bundle.putSerializable(String, Serializable)并进行隐式转换:Serializable serializable = foo;,这似乎不太可能.实际上,当我调试时,我可以看到Foo被放入Bundle中,并且可以检查Bundle并在其中看到Foo的实例,但是在检索它时,强制转换失败.

I'm not sure it's relevant, but I'm packing this in a jar for use with Android. The code that uses these classes include putting them in Bundles which is why I need Serializable. I considered that perhaps somehow ProGuard thinks that Foo is never used as a Serializable but that seems unlikely given that I pass it as a parameter to Bundle.putSerializable(String, Serializable) and also I do an implicit cast: Serializable serializable = foo;. In fact, when I debug, I can see the Foo get put into the Bundle and I can examine the Bundle and see the instance of Foo there, but when retrieving it the cast fails.

推荐答案

ProGuard从未从库(如Serializable)中定义的接口从已处理代码(如Foo)中的类中剥离.库代码可能会强制转换为这些接口,因此无法将其删除.

ProGuard doesn't ever strip interfaces that are defined in libraries (like Serializable) from classes in code that is processed (like Foo). Library code may be casting to those interfaces, so they can't be removed.

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

I get null after I cast from Serializable to Foo

这意味着实例必须以null开头.如果您收到ClassCastException,则您的分析将是正确的.您可以检查Foo是否仍使用javap实现Serializable.问题可能出在其他地方.有关序列化的提示,请查看ProGuard手册>示例> 处理可序列化的类.

This means that the instance must be null to start with. Your analysis would be correct if you'd get a ClassCastException. You can check that Foo still implements Serializable with javap. The problem probably lies elsewhere. For tips on serialization, you can look at the ProGuard manual > Examples > Processing serializable classes.

更新:

在这种情况下,事实证明这是配置问题.仅当ProGuard知道类文件的所有知识时,它才能处理类文件(就像编译器一样).您确实必须指定运行时类:

In this case, it turns out to be a configuration problem. ProGuard can only process class files if it knows everything about their hierarchy (just like a compiler). You really have to specify the runtime classes:

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

或对于Android:

or for Android:

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

Android Ant/Eclipse构建会自动为您指定所有必需的-injars/-outjars/-libraryjars选项,但是在自定义构建过程中,您必须自己指定它们. CFR. ProGuard手册>示例> 完整的Android应用程序.

The Android Ant/Eclipse builds automatically specify all necessary -injars/-outjars/-libraryjars options for you, but in a custom build process, you have to specify them yourself. Cfr. ProGuard manual > Examples > A complete Android application.

请注意,选项-dontwarn可以使警告消失,而不能使问题消失.仅在确实需要时使用它.

Note that the option -dontwarn makes the warnings go away, but not the problems. Only use it if really necessary.

这篇关于如何阻止ProGuard从类中剥离Serializable接口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆