Proguard - Error: A JNI error has occured

半腔热情 提交于 2019-12-24 01:13:07

问题


I've been trying to use ProGuard to obfuscate an application of mine. I have disabled every option exception for obfuscate. Loader is my main class.

The screenshot below is the result when I try to run my obfuscated jar. No errors were given while obfuscating either.

My config

-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

回答1:


If this is the only configuration that you are using, also native methods will get obfuscated. As a result, their name will not match the ones in the native library anymore, and thus you will see an error like this when trying to load the library using System.loadLibrary.

You need to add at least a rule like this:

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

This will instruct ProGuard to keep all native methods in any class it processes.

Edit:

Additional rules that are needed to get it working:

  • Remove -dontpreverify, preverify is needed for Java 7+
  • Keep the main method

This will keep the main method:

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



回答2:


You have to exclude certain classes from obfuscating like bean classes, callback classes and native classes. In the official examples the following is mentioned:

Processing native methods

If your application, applet, servlet, library, etc., contains native methods, you'll want to preserve their names and their classes' names, so they can still be linked to the native library.

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

Note: We don't want to preserve all classes or all native methods; we just want to keep the relevant names from being obfuscated.

Processing callback methods

If your application, applet, servlet, library, etc., contains callback methods, which are called from external code (native code, scripts,...), you'll want to preserve them, and probably their classes too. They are just entry points to your code, much like, say, the main method of an application.

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

Processing bean classes

If your application, applet, servlet, library, etc., makes extensive use of introspection on bean classes to find bean editor classes, or getter and setter methods, then configuration may become painful. There's not much else you can do than making sure the bean class names, or the getter and setter names don't change

Helpful: to use wildcards in class names and method signatures

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

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

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

Also some other scenarios (Ressources, Serialization classes) can lead to problems. Please refer to the whole guide for these

ProGuard Official: Examples



来源:https://stackoverflow.com/questions/38151653/proguard-error-a-jni-error-has-occured

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!