Proguard - 错误:发生了JNI错误

时间:2016-07-01 18:14:18

标签: java proguard

我一直在尝试使用ProGuard来混淆我的应用程序。我已经禁用了混淆的每个选项异常。装载机是我的主要课程。

下面的屏幕截图是我尝试运行模糊jar时的结果。 混淆时也没有错误。

enter image description here

我的配置

-injars 'C:\Users\Corsair\Desktop\obfuscate\Example.jar'
-outjars 'C:\Users\Corsair\Desktop\obfuscate\ExampleOut.jar'

-libraryjars 'C:\Program Files\Java\jre1.8.0_91\lib\rt.jar'

-dontskipnonpubliclibraryclassmembers
-dontshrink
-dontoptimize
-dontusemixedcaseclassnames
-dontpreverify
-dontnote
-dontwarn

-verbose

-keep class Loader

2 个答案:

答案 0 :(得分:6)

如果这是您使用的唯一配置,则本机方法也会被混淆。因此,他们的名称将不再与本机库中的名称相匹配,因此当您尝试使用System.loadLibrary加载库时,您会看到类似的错误。

您需要添加至少一个这样的规则:

-keepclasseswithmembernames,includedescriptorclasses class * {
    native <methods>;
}

这将指示ProGuard将所有本机方法保留在它处理的任何类中。

编辑:

使其运作所需的其他规则:

  • 删除-dontpreverify,Java 7 +
  • 需要预验证
  • 保留主要方法

这将保留主要方法:

-keep class Loader {
    public static void main(...);
}

答案 1 :(得分:4)

您必须将某些类排除在混淆类似bean类,回调类和本机类之外。在官方的例子中提到了以下内容:

处理原生方法

如果你的应用程序,applet,servlet,库等包含本机方法,你需要保留它们的名称和类的名称,这样它们仍然可以链接到本机库。

-keepclasseswithmembernames,includedescriptorclasses class * {
    native <methods>;
}

注意:我们不想保留所有类或所有本机方法;我们只是希望保持相关名称不被混淆。

处理回调方法

如果您的应用程序,applet,servlet,库等包含从外部代码(本机代码,脚本......)调用的回调方法,您将希望保留它们,也可能保留它们的类。它们只是代码的入口点,就像应用程序的主要方法一样。

-keep class mypackage.MyCallbackClass {
    void myCallbackMethod(java.lang.String);
}

处理bean类

如果你的应用程序,applet,servlet,库等广泛使用bean类的内省来查找bean编辑器类,或getter和setter方法,那么配置可能会变得很痛苦。除了确保bean类名称或getter和setter名称不会更改之外,您无法做其他事情

有用:在类名和方法签名中使用通配符

-keep class mybeans.** {
    void set*(***);
    void set*(int, ***);

    boolean is*(); 
    boolean is*(int);

    *** get*();
    *** get*(int);
}

另外一些场景(Ressources,Serialization classes)可能会导致问题。请参阅这些

的整个指南

ProGuard Official: Examples