问题描述
我未混淆的代码有效。.
在进行Proguard混淆处理时-仅通过1次优化 我收到以下错误:
Exception in thread "main" java.lang.Error: Structure.getFieldOrder() on class com.sun.jna.platform.mac.SystemB$Timeval does not provide enough names [0] ([]) to match declared fields [2] ([tv_sec,tv_usec])
at com.sun.jna.Structure.getFields(UnkNown Source)
at com.sun.jna.Structure.deriveLayout(UnkNown Source)
at com.sun.jna.Structure.calculateSize(UnkNown Source)
at com.sun.jna.Structure.allocateMemory(UnkNown Source)
at com.sun.jna.Structure.ensureAllocated(UnkNown Source)
at com.sun.jna.Structure.ensureAllocated(UnkNown Source)
at com.sun.jna.Structure.getPointer(UnkNown Source)
at oshi.util.platform.mac.SysctlUtil.sysctl(UnkNown Source)
at oshi.software.os.mac.MacoperatingSystem.<clinit>(UnkNown Source)
at oshi.SystemInfo.createOperatingSystem(UnkNown Source)
at oshi.util.Memoizer$1.get(UnkNown Source)
at oshi.SystemInfo.getoperatingSystem(UnkNown Source)
我在keep指令上尝试了以下几种方法:
-keep class com.sun.** { *; }
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
-keep class com.sun.jna.**{ *; }
-keep class * implements com.sun.jna.**{ *; }
-keep class oshi.**{ *; }
-keep class * implements oshi.**{ *; }
-keepclassmembers class * extends com.sun.jna.** {
<fields>;
<methods>;
}
-keepclassmembers class * extends oshi.** {
<fields>;
<methods>;
}
如何配置Proguard以避免此异常?
解决方法
从JNA 5.x开始,Structure
类字段由@FieldOrder
注释标识。对于导致问题的Timeval
结构,其定义如下:
@Structure.FieldOrder({ "tv_sec","tv_usec" })
class Timeval extends Structure {
public NativeLong tv_sec; // seconds
public int tv_usec; // microseconds
}
堆栈跟踪表明它正在(正确地)找到public
字段,但未找到注释声明的字段顺序。
This question表示Proguard将混淆注释,这很可能是问题的根源。
JNA's FAQ建议使用以下语法。可能需要更广泛的通配符定义,而不是显式定义<fields>
和<methods>
。
-dontwarn java.awt.*
-keep class com.sun.jna.* { *; }
-keepclassmembers class * extends com.sun.jna.* { public *; }
由于注释在JNA的Structure类中定义为@interface
,因此this question的答案所建议的解决方案表明以下应解决的问题:
# Annotated interfaces (including methods which are also kept in implementing classes)
-keep @com.sun.jna.Structure.FieldOrder interface * {
*;
}
可能更广泛使用的其他解决方案:
-
-keepattributes Annotation
-
-keepattributes *Annotation*