如何阻止Proguard删除返回类型?

时间:2014-07-22 08:25:49

标签: java proguard

我最近第一次启用了Proguard的混淆功能,它似乎找到了我的保护规则中的所有漏洞。

我的保留规则是使用注释定义的:注释元素将保持不变。随后的配置看起来像这样:

# Keep the annotation.
-keep @interface org.mozilla.gecko.mozglue.JNITarget

# Keep classes tagged with the annotation.
-keep @org.mozilla.gecko.mozglue.JNITarget class *

# Keep all members of an annotated class.
-keepclassmembers @org.mozilla.gecko.mozglue.JNITarget class * {
    *;
}

# Keep annotated members of any class.
-keepclassmembers class * {
    @org.mozilla.gecko.mozglue.JNITarget *;
}

# Keep classes which contain at least one annotated element. Split over two directives
# because, according to the developer of ProGuard, "the option -keepclasseswithmembers
# doesn't combine well with the '*' wildcard" (And, indeed, using it causes things to
# be deleted that we want to keep.)
-keepclasseswithmembers class * {
    @org.mozilla.gecko.mozglue.JNITarget <methods>;
}
-keepclasseswithmembers class * {
    @org.mozilla.gecko.mozglue.JNITarget <fields>;
}

来自Reflection / JNI / etc的Java的所有入口点。使用此注释(或等效配置但名称更好的注释)进行注释。

不幸的是,这并不能阻止Proguard重命名用作方法的返回类型的类,从而改变其签名并打破入口点。

例如,Javap揭示了带签名的方法:

 public org.mozilla.gecko.Tab loadUrl(java.lang.String);

来自Proguard看起来像:

 public mt loadUrl(java.lang.String);

尽管被注释了。

那么,保持依赖类的神秘语法是什么?似乎很奇怪,告诉它我希望保留一个入口点,无论如何它都会腐败它......

1 个答案:

答案 0 :(得分:2)

这是预期的行为。在某些情况下,在早期版本中,ProGuard会自动保留所有返回类型和参数类型,但对于许多开发人员来说,结果却是不必要的和令人困惑的。

例如,对于使用Class#getMethod的反射,返回类型不相关。

如果不保留此类型,ProGuard现在可以打印出笔记。然后,您仍然可以为它添加一条保养线。

请参阅ProGuard手册&gt;疑难解答&gt; Note: the configuration keeps the entry point '...', but not the descriptor class '...'

<强>更新

ProGuard 5.0 beta3及更高版本的支持

-keep,includedescriptorclasses .......

还自动将类保存在指定的字段类型,返回类型和参数类型中。