草庐IT

java - 谁能解释 Proguard 配置设置 : -keep @interface *

coder 2024-04-05 原文

这是有问题的配置设置:-keep @interface *

这篇文章中引用了此设置:https://stackoverflow.com/a/17437740/367544

Proguard 手册中的此处:https://www.guardsquare.com/en/proguard/manual/troubleshooting#notkept

但手册(或帖子)并未解释此配置设置的工作原理或原因。我认为此配置值会保留在您的应用程序中定义 的任何注释。我在这里强调 defined 这个词是因为我想将它与 used 注释的地方进行比较。因此,如果我在我的代码中定义了一个注释,如 public @interface MyAnnotation {}那么我希望这个配置设置能够保留它。但是,如果我要在另一个类中使用我的注释,如 public class MyClass { @MyAnnotation public void run(){} }那么我希望此配置设置保留在那里。我认为要在使用注释的地方保留注释,您需要像 -keep class * { @interface <methods>; } 这样的设置。 .但是,我的理解显然是错误的,因为 -keep @interface *配置设置确实使用的地方保留注释。

谁能解释为什么 -keep @interface *配置设置会影响在其他类中使用的注释吗?此外,Proguard 手册从未解释如何使用 @interface关键字。这就像任何注释的通配符吗?或者它是否像我的示例中那样引用注释的定义 public @interface MyAnnotation {} ?还是完全不同?

最佳答案

当每个接口(interface)都被编译时,即使使用混淆器,它也应该创建一个可以在 java 虚拟机中使用的有效类文件。 Java 有特定的命名规则,用于将包中的接口(interface)和类与文件连接起来。

所以例如即使接口(interface)VeryImportantInterface包裹数量 com.mycompany.mypackage被混淆了,结果你得到: 界面 a在包装内 b.c.d java 期望找到接口(interface) a在包装内 b.c.d在名为 a.class 的文件中

类似的规则适用于内部类和接口(interface)。

因此,如果您确实混淆了类或接口(interface)的定义,则必须在任何地方都提及其混淆后的名称。否则,例如类 MyClass.class混淆为 a.class和另一类,例如MyClassReference仍将此类引用为 MyClass然后是ClassNotFoundException将在 MyClassReference 时抛出尝试使用 MyClass第一次。

关于-keep @interface *ProGuard RefCard 中所述

'keep' prevents classes and class members from being removed or renamed.

ProGuard RefCard还提到通配符 *可以用

  1. * can be used for any number of characters (but not the package separator)
  2. the class name * refers to any class, irrespective of its package.
  3. * matches any field or method

所以 -keep @interface *根据以上定义适用于 public @interface MyAnnotation {}因为它的名字匹配通配符 * .因为根据定义 MyAnnotation不会被删除,它不会从任何地方删除。

相反-keep class * { @interface <methods>; }更具体,只会保留注释的用法。

要考虑的另一件事是 keep后面跟着一个 Class specification .并基于 Class specification

The @ specifications can be used to restrict classes and class members to the ones that are annotated with the specified annotation types. An annotationtype is specified just like a classname.

pro guard在收缩过程中会删除所有直接或间接使用的方法和成员加上-keep指定的方法和成员.但是它没有明确提及它对注释的作用。 Pro-Guard 提到缩小以下内容:

By default, shrinking is applied; all classes and class members are removed, except for the ones listed by the various -keep options, and the ones on which they depend, directly or indirectly. Shrinking Options So one case could be that pro-guard somehow detects that the annotation is used and prevents it from beeing removed during shrinking. Another case would be that the annotations are considered metadatum of the methods and not beeing considered members. It is really not obvious or well documented in proguard documentation.

您可以使用 -whyareyoukeeping @interface *-verbose从 Prog-Guard 获得有关保留相关接口(interface)的原因的反馈。

更新: 由于上述配置指令的结果是: ... is kept by a directive in the configuration. , 只能得出结论 -keep @interface *实际上 。因此,它没有提供任何额外的说明。在没有对 Pro-Guard 文档进行任何具体解释的情况下,我认为可能有以下 2 种可能的解释: 1. proguard shrinking step 认为注释在代码的某些部分使用,因此需要并且不减少。 2. class_specification @interface *匹配带注释的方法和注释声明。

关于java - 谁能解释 Proguard 配置设置 : -keep @interface *,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49962245/

有关java - 谁能解释 Proguard 配置设置 : -keep @interface *的更多相关文章

  1. ruby - 使用 RubyZip 生成 ZIP 文件时设置压缩级别 - 2

    我有一个Ruby程序,它使用rubyzip压缩XML文件的目录树。gem。我的问题是文件开始变得很重,我想提高压缩级别,因为压缩时间不是问题。我在rubyzipdocumentation中找不到一种为创建的ZIP文件指定压缩级别的方法。有人知道如何更改此设置吗?是否有另一个允许指定压缩级别的Ruby库? 最佳答案 这是我通过查看ruby​​zip内部创建的代码。level=Zlib::BEST_COMPRESSIONZip::ZipOutputStream.open(zip_file)do|zip|Dir.glob("**/*")d

  2. ruby-on-rails - rails : keeping DRY with ActiveRecord models that share similar complex attributes - 2

    这似乎应该有一个直截了当的答案,但在Google上花了很多时间,所以我找不到它。这可能是缺少正确关键字的情况。在我的RoR应用程序中,我有几个模型共享一种特定类型的字符串属性,该属性具有特殊验证和其他功能。我能想到的最接近的类似示例是表示URL的字符串。这会导致模型中出现大量重复(甚至单元测试中会出现更多重复),但我不确定如何让它更DRY。我能想到几个可能的方向...按照“validates_url_format_of”插件,但这只会让验证干给这个特殊的字符串它自己的模型,但这看起来很像重溶液为这个特殊的字符串创建一个ruby​​类,但是我如何得到ActiveRecord关联这个类模型

  3. ruby-openid:执行发现时未设置@socket - 2

    我在使用omniauth/openid时遇到了一些麻烦。在尝试进行身份验证时,我在日志中发现了这一点:OpenID::FetchingError:Errorfetchinghttps://www.google.com/accounts/o8/.well-known/host-meta?hd=profiles.google.com%2Fmy_username:undefinedmethod`io'fornil:NilClass重要的是undefinedmethodio'fornil:NilClass来自openid/fetchers.rb,在下面的代码片段中:moduleNetclass

  4. ruby-on-rails - 如何使用 instance_variable_set 正确设置实例变量? - 2

    我正在查看instance_variable_set的文档并看到给出的示例代码是这样做的:obj.instance_variable_set(:@instnc_var,"valuefortheinstancevariable")然后允许您在类的任何实例方法中以@instnc_var的形式访问该变量。我想知道为什么在@instnc_var之前需要一个冒号:。冒号有什么作用? 最佳答案 我的第一直觉是告诉你不要使用instance_variable_set除非你真的知道你用它做什么。它本质上是一种元编程工具或绕过实例变量可见性的黑客攻击

  5. ruby-on-rails - 独立 ruby​​ 脚本的配置文件 - 2

    我有一个在Linux服务器上运行的ruby​​脚本。它不使用rails或任何东西。它基本上是一个命令行ruby​​脚本,可以像这样传递参数:./ruby_script.rbarg1arg2如何将参数抽象到配置文件(例如yaml文件或其他文件)中?您能否举例说明如何做到这一点?提前谢谢你。 最佳答案 首先,您可以运行一个写入YAML配置文件的独立脚本:require"yaml"File.write("path_to_yaml_file",[arg1,arg2].to_yaml)然后,在您的应用中阅读它:require"yaml"arg

  6. java - 等价于 Java 中的 Ruby Hash - 2

    我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/

  7. ruby-on-rails - date_field_tag,如何设置默认日期? [ rails 上的 ruby ] - 2

    我想设置一个默认日期,例如实际日期,我该如何设置?还有如何在组合框中设置默认值顺便问一下,date_field_tag和date_field之间有什么区别? 最佳答案 试试这个:将默认日期作为第二个参数传递。youcorrectlysetthedefaultvalueofcomboboxasshowninyourquestion. 关于ruby-on-rails-date_field_tag,如何设置默认日期?[rails上的ruby],我们在StackOverflow上找到一个类似的问

  8. Ruby Sinatra 配置用于生产和开发 - 2

    我已经在Sinatra上创建了应用程序,它代表了一个简单的API。我想在生产和开发上进行部署。我想在部署时选择,是开发还是生产,一些方法的逻辑应该改变,这取决于部署类型。是否有任何想法,如何完成以及解决此问题的一些示例。例子:我有代码get'/api/test'doreturn"Itisdev"end但是在部署到生产环境之后我想在运行/api/test之后看到ItisPROD如何实现? 最佳答案 根据SinatraDocumentation:EnvironmentscanbesetthroughtheRACK_ENVenvironm

  9. ruby - 有人可以帮助解释类创建的 post_initialize 回调吗 (Sandi Metz) - 2

    我正在阅读SandiMetz的POODR,并且遇到了一个我不太了解的编码原则。这是代码:classBicycleattr_reader:size,:chain,:tire_sizedefinitialize(args={})@size=args[:size]||1@chain=args[:chain]||2@tire_size=args[:tire_size]||3post_initialize(args)endendclassMountainBike此代码将为其各自的属性输出1,2,3,4,5。我不明白的是查找方法。当一辆山地自行车被实例化时,因为它没有自己的initialize方法

  10. ruby-on-rails - 在 Rails 开发环境中为 .ogv 文件设置 Mime 类型 - 2

    我正在玩HTML5视频并且在ERB中有以下片段:mp4视频从在我的开发环境中运行的服务器很好地流式传输到chrome。然而firefox显示带有海报图像的视频播放器,但带有一个大X。问题似乎是mongrel不确定ogv扩展的mime类型,并且只返回text/plain,如curl所示:$curl-Ihttp://0.0.0.0:3000/pr6.ogvHTTP/1.1200OKConnection:closeDate:Mon,19Apr201012:33:50GMTLast-Modified:Sun,18Apr201012:46:07GMTContent-Type:text/plain

随机推荐