使用progaurd混淆JNA结构时,getFieldOrder中的异常

问题描述

我未混淆的代码有效。.

在进行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*

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...