提供以下课程
package com.example;
public class ProguardConstantFieldUsageDemo {
private static final String CONSTANT_FIELD = "I'm not dead!";
public String publicMethodUsingConstant() {
return CONSTANT_FIELD + "I agree, you are not dead.";
}
}
和要求进行死代码分析的配置
...
-dontoptimize
-dontobfuscate
-dontpreverify
-printusage result
... + keep statement to keep the public method
proguard(版本6.2.2)声称常量字段为无效代码:
com.example.ProguardConstantFieldUsageDemo:
private static final java.lang.String CONSTANT_FIELD
这是proguard的错误还是功能(由javac内联引起的错误),还是有一种方法可以配置proguard使其不产生误报?
这是由javac内联常量引起的:
javap -l -c -constants -cp THEJAR com.example.ProguardConstantFieldUsageDemo
输出
...
0: ldc #3 // String I'm not dead!I agree
...
因此常量实际上在字节码中不存在。非静态字段和非最终字段也似乎发生了同样的情况。
解决方案是将proguard配置为保留所有私有字段:
-keepclassmembers class * {
private <fields>;
}
这还将抑制有关实际死场的警告,但这不是一个大问题,因为其他静态分析器可以发现它们,因为它们是私有的。