英文:
Exception in getFieldOrder() when obfuscating JNA Structure using progaurd
问题
我的未混淆代码是正常工作的。
但是当通过 Proguard 混淆后——只进行了一次优化——我得到了以下错误:
Exception in thread "main" java.lang.Error: Structure.getFieldOrder() 在类 com.sun.jna.platform.mac.SystemB$Timeval 上未提供足够的名称 [0] ([]) 以匹配已声明的字段 [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 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 以避免此异常呢?
英文:
My un-obfuscated code works..
When run through Proguard obfuscation -- just 1 pass optimization
I am getting the following error:
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)
I tried several on keep directive as follows:
-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>;
}
How can I configure Proguard to avoid this exception?
答案1
得分: 1
Beginning with JNA 5.x, the Structure
class fields are identified with the @FieldOrder
annotation. For the Timeval
structure causing your problem, it's defined like this:
@Structure.FieldOrder({ "tv_sec", "tv_usec" })
class Timeval extends Structure {
public NativeLong tv_sec; // seconds
public int tv_usec; // microseconds
}
The stack trace indicates it's finding the public
fields (correctly) but not finding the field order declared by the annotation.
This question indicates that Proguard will obfuscate annotations, which is likely the source of the problem.
JNA's FAQ suggests the following syntax. It's possible the more broad wildcard definition is necessary rather than explicitly defining <fields>
and <methods>
.
-dontwarn java.awt.*
-keep class com.sun.jna.* { *; }
-keepclassmembers class * extends com.sun.jna.* { public *; }
Since the annotation is defined in JNA's Structure class as an @interface
, the solution suggested by answers to this question indicate the following should fix the problem:
# Annotated interfaces (including methods which are also kept in implementing classes)
-keep @com.sun.jna.Structure.FieldOrder interface * {
*;
}
Other solutions that may work, more broadly:
-keepattributes Annotation
-keepattributes *Annotation*
英文:
Beginning with JNA 5.x, the Structure
class fields are identified with the @FieldOrder
annotation. For the Timeval
structure causing your problem, it's defined like this:
@Structure.FieldOrder({ "tv_sec", "tv_usec" })
class Timeval extends Structure {
public NativeLong tv_sec; // seconds
public int tv_usec; // microseconds
}
The stack trace indicates it's finding the public
fields (correctly) but not finding the field order declared by the annotation.
This question indicates that Proguard will obfuscate annotations, which is likely the source of the problem.
JNA's FAQ suggests the following syntax. It's possible the more broad wildcard definition is necessary rather than explicitly defining <fields>
and <methods>
.
-dontwarn java.awt.*
-keep class com.sun.jna.* { *; }
-keepclassmembers class * extends com.sun.jna.* { public *; }
Since the annotation is defined in JNA's Structure class as an @interface
, the solution suggested by answers to this question indicate the following should fix the problem:
# Annotated interfaces (including methods which are also kept in implementing classes)
-keep @com.sun.jna.Structure.FieldOrder interface * {
*;
}
Other solutions that may work, more broadly:
-keepattributes Annotation
-keepattributes *Annotation*
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论