【问题标题】:Proguard - Error: A JNI error has occuredProguard - 错误:发生了 JNI 错误
【发布时间】:2016-07-01 18:14:17
【问题描述】:

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

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

我的配置

-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

【问题讨论】:

    标签: java proguard


    【解决方案1】:

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

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

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

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

    编辑:

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

    • 去掉-dontpreverify,Java 7+需要预验证
    • 保留main方法

    这将保留main方法:

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

    【讨论】:

    • 您好,非常感谢您的帮助,我添加了它,但我仍然收到错误消息!这是我现在的配置pastebin.com/bnhvYGaT
    • 也许您可以将您的输出 jar 粘贴到某个地方,以便我们对其进行检查。
    • 当然,我真的不知道在哪里上传它所以我把它放在Github上。 github.com/SJ19/ProGuardTest
    • 好的,谢谢,我用所需的其他规则更新了答案。之后,该应用程序对我来说启动得很好。
    • 它现在正在工作,我不能感谢你足够的人!我似乎还不能给你赏金,但我会尽快给你。另外,如果您不介意,您能否建议我最好的 myconfig.pro 设置是什么?我真的没有任何需求,我只是希望它在不破坏应用程序的情况下尽可能安全。
    【解决方案2】:

    您必须从混淆中排除某些类,例如 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);
    }
    

    还有一些其他场景(资源、序列化类)可能会导致问题。有关这些,请参阅整个指南

    ProGuard Official: Examples

    【讨论】:

    • 非常感谢您的帮助,尽管我仍然收到同样的错误!这是我的配置。 pastebin.com/bnhvYGaT
    猜你喜欢
    • 1970-01-01
    • 2017-06-21
    • 1970-01-01
    • 1970-01-01
    • 2020-12-01
    • 2019-06-05
    • 1970-01-01
    • 2020-10-10
    相关资源
    最近更新 更多