Faheem Raza
Faheem Raza

Reputation: 199

java.lang.UnsatisfiedLinkError: No implementation found for Boolean

I use ".so" files in my project but it give following error "java.lang.UnsatisfiedLinkError: No implementation found for Boolean", i already try to recreate ".so" using Cygwin and put it in jniLibs folder and also using create a jar of it, but it gives same error.

But the same ".so" file is working in my existing project. I try so many ways but its not working at all, what can i do ?

com.amaze.filemanager E/art: No implementation found for boolean com.amaze.filemanager.scanner.SignatureLib.InitScanner(java.lang.String, java.lang.String) (tried Java_com_amaze_filemanager_scanner_SignatureLib_InitScanner and Java_com_amaze_filemanager_scanner_SignatureLib_InitScanner__Ljava_lang_String_2Ljava_lang_String_2) 12-19 11:47:07.463 4579-4934/com.amaze.filemanager E/AndroidRuntime: FATAL EXCEPTION: Thread-5230 Process: com.amaze.filemanager, PID: 4579 java.lang.UnsatisfiedLinkError: No implementation found for boolean com.amaze.filemanager.scanner.SignatureLib.InitScanner(java.lang.String, java.lang.String) (tried Java_com_amaze_filemanager_scanner_SignatureLib_InitScanner and Java_com_amaze_filemanager_scanner_SignatureLib_InitScanner__Ljava_lang_String_2Ljava_lang_String_2) at com.amaze.filemanager.scanner.SignatureLib.InitScanner(Native Method) at com.amaze.filemanager.scanner.SignatureLib.InitializeScanner(SignatureLib.java:42) at com.amaze.filemanager.scanner.Signature.(Signature.java:62) at com.amaze.filemanager.ScanForVirusActivity$1.run(ScanForVirusActivity.java:66)

public class SignatureLib {

    static {
        System.loadLibrary("Signature");
    }

    SharedPreferencesUtils spu;
    Context context;

    public SignatureLib(Context context) {
        this.context = context;
    }

    private native boolean InitScanner(String strDBPath, String dbPathTemp);

    private native boolean DeInitScanner();

    private native String checkVirus(String filepath);

    private native boolean UploadFile(String FilePath, String DeviceID, String path);

    private native boolean DownloadFile(String FilePath, String DeviceID, String path);

    private native boolean IsGameApp(String AppName);

    private native boolean SetUpdateInProgressStatus(boolean bStatus);

    public boolean InitializeScanner(String strDBPath) {

        spu = new SharedPreferencesUtils();
        String packageName = context.getPackageName();
        String dbPathTemp = "data/data/" + packageName + "/";

        return InitScanner(strDBPath, dbPathTemp);
    }

}

Upvotes: 6

Views: 14883

Answers (2)

Naval Kishor Jha
Naval Kishor Jha

Reputation: 914

In My java file, i have loaded my library name named as "native-lib" in below static block

package primeno.naval.com.primenumberusingndk;
static
{
  System.loadLibrary("native-lib");
}

here I have declared the two functions and their implementation is in CPP file

public native String stringFromJNI();
public native boolean isPrime(int n);

my cpp file with above function implementation

extern "C"
JNIEXPORT jstring JNICALL Java_primeno_naval_com_primenumberusingndk_MainActivity_stringFromJNI(
JNIEnv *env,
jobject /* this */) {
std::string hello = "Hello from C++";
return env->NewStringUTF(hello.c_str());
}

extern "C"
JNIEXPORT jboolean JNICALL Java_primeno_naval_com_primenumberusingndk_MainActivity_isPrime(JNIEnv *env,jobject ,jint no)
{
PrimeNumber primeNumber(no);
return primeNumber.isPrime();
}

or you can do in this way also

extern "C" {

    JNIEXPORT jstring JNICALL Java_primeno_naval_com_primenumberusingndk_MainActivity_stringFromJNI(
    JNIEnv *env,
    jobject /* this */) {
    std::string hello = "Hello from C++";
    return env->NewStringUTF(hello.c_str());
    }

    JNIEXPORT jboolean JNICALL Java_primeno_naval_com_primenumberusingndk_MainActivity_isPrime(JNIEnv *env,jobject ,jint no)
    {
    PrimeNumber primeNumber(no);
    return primeNumber.isPrime();
    }
}

If mismatch in name of function and signature is not the case then you have to write the extern "C" before each function in cpp file, so actual format of naming convention is

extern "C" JNIEXPORT <RETURN_TYPE> JNICALL Java_<PACKAGE_NAME>_<JAVA_CLASS>_<METHOD_NAME>(
JNIEnv *env, jobject obj, <METHOD_PARAMETERS>...) {
...
}

extern "C":

Statement to make C++ function names have C linkage. To support function overloading, C++ compilers mangle function names, which means C++ function names are not the same as in C. Without extern "C", your native functions' signatures will not match their declarations in Java (at runtime). Long story short, you need this statement for every method if you are writing native C++ and not C.

JNIEXPORT:

Contains compiler directives required to ensure the function is exported properly.

<RETURN_TYPE>:

Return type of the JNI method, usually a native version of a Java type. For example, in the method you just wrote above, you are returning a jstring, which is the native equivalent of String in Java.

JNICALL: C

ontains compiler directives required to ensure the function is treated with the proper JNI calling convention.

<JAVA_CLASS>:

The connecting Java class this function is tied to. In our example, this would be MainActivity, since that's the Java class that will use this function.

<PACKAGE_NAME>:

The package name where the previously defined <JAVA_CLASS> resides in. Replace dots (.) with underscores (_).

<METHOD_NAME>:

This name should be the same as the one you declare inside the connecting . In our example, we declared the native method getNativeString(). In this case, should also be getNativeString().

JNIEnv *env:

Pointer to a structure (a function table, to be exact) storing all JNI helper function pointers, including the one we call in our example, NewStringUTF(string). To be able to use these functions, you will need to #include .

jobject obj:

Java object corresponding to the connecting<JAVA_CLASS>.

<METHOD_PARAMETERS>...:

Comma delimited list of input arguments the native method is supposed to take. In our example, we do not have any input arguments for our getNativeString() function, and is hence left blank.

Upvotes: 1

Gabe Sechan
Gabe Sechan

Reputation: 93678

Yeah, the full stack trace was needed- you broke it off initially in a place that made no sense. What its saying is that your .so file doesn't have an InitScanner function- either you misnamed it in the C file, you got the signature wrong, or it isn't there at all. Or if you used C++, you forgot to extern C the function.

Upvotes: 2

Related Questions