ProGuard忽略注释默认值

Phi*_*wak 5 java annotations proguard

问题

我在使用proguard-maven-plugin(github.com/wvengen/proguard-maven-plugin)时遇到ProGuard 4.11(可以优化,缩小和混淆Java代码的应用程序)的问题(尽管这不重要)那么多,因为错误是在运行时发生的,并且maven插件只是用我知道的一些参数调用二进制文件).

我有一个注释类,它被这样结构化(没什么特别的):

@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD)
public @interface SqlValueCache {
  String value();

  SqlValueCache.Type type() default Type.OBJECT_UPDATE; //Type is just an ordinary enum
}
Run Code Online (Sandbox Code Playgroud)

我也有一些使用该注释注释的字段,但我正在跳过type()参数,因为我想使用默认值:

 @SqlValueCache("nickname")
 protected SqlValueHolder<String> nick;
Run Code Online (Sandbox Code Playgroud)

现在我想在运行时处理该注释:

SqlValueCache annotation = field.getAnnotation(SqlValueCache.class); //Skipped the validation
annotation.value(); //Works fine, because specified
annotation.type(); //java.lang.annotation.IncompleteAnnotationException, *not* using the default
Run Code Online (Sandbox Code Playgroud)

如上面的评论所述,我得到一个IncompleteAnnotationException,说明我的注释声明缺少type()值.但是这个价值应该被暗示default Type.OBJECT_UPDATE!所以现在我想知道,为什么会这样?

假设

我假设default的东西储存在某种属性,我需要指定的-keepattributes,但我一直无法弄清楚,如果这是真的还是哪一个是.

再生产

不使用ProGuard时,它确实可以正常工作.

我还确保问题实际上是缺少的隐含值 - 代码在使用ProGuard时按预期运行,但明确指定了type(),如下所示:

 @SqlValueCache(value = "nickname", type = Type.OBJECT_UPDATE)
 protected SqlValueHolder<String> nick;
Run Code Online (Sandbox Code Playgroud)

我使用这种方法作为临时解决方法,但在我看来,这不是最漂亮的解决方案.另外,如上所述,我仍然想知道为什么会发生这种错误.

提前感谢阅读和调查我的问题!:)

附录/元

是的,我确实在网上搜索解决方案,并且还使用了StackOverflow搜索框.使用这个问题的标题和各种其他搜索查询,我只能找到抱怨根本没有注释或者要求保留类的子类注释的问题等等.我也搜索了异常,但唯一有用的结果是JavaDoc(docs.oracle.com/javase/7/docs/api/java/lang/annotation/IncompleteAnnotationException.html)我遇到的异常.

我很抱歉这些链接,但我显然需要10个声望发布超过两个,虽然我真的喜欢链接东西:/

堆栈跟踪

我已经附加了我在控制台中获得的Stacktrace(在我看来,类名根本不会有用 - 如果真的有必要,我可以附加它们;我的类也由自定义类加载器加载,但我怀疑这有什么区别):

java.lang.ExceptionInInitializerError
at <class with annotated field>
(...)
Caused by: java.lang.annotation.IncompleteAnnotationException: io.github.xxyy.common.sql.builder.annotation.SqlValueCache missing element type
at sun.reflect.annotation.AnnotationInvocationHandler.invoke(AnnotationInvocationHandler.java:72) ~[?:1.7.0_51]
at com.sun.proxy.$Proxy18.type(Unknown Source)
at <line accessing type() of SqlValueCache>
(...)
Run Code Online (Sandbox Code Playgroud)

ProGuard配置

这是我的ProGuard配置,如果有任何帮助(这是我发现与此问题相关的部分 - 完整文件:pastebin.com/u6wt00cj):

-dontskipnonpubliclibraryclassmembers
-target 1.7
-dontshrink
-dontoptimize
-repackageclasses io.github.xxyy.obf.towerdefense.client
-keepattributes SourceFile,LineNumberTable,*Annotations*,LocalVariable*Table

-keep,allowobfuscation class ** {
    <fields>;
    <methods>;
}

-keep,allowshrinking class **.annotation** {
    <fields>;
    <methods>;
}

# Also keep - Enumerations. Keep the special static methods that are required in
# enumeration classes.
-keepclassmembers enum  ** {
  public static **[] values();
  public static ** valueOf(java.lang.String);
}
Run Code Online (Sandbox Code Playgroud)

Eri*_*une 3

您还需要保留AnnotationDefault属性:

-keepattributes AnnotationDefault
Run Code Online (Sandbox Code Playgroud)

您可以通过在当前选项中更改*Annotations*为来获得相同的效果,因此通配符匹配。*Annotation*-keepattributesAnnotationDefault