java.lang.UnsatisfiedLinkError: No implementation found for Boolean
Asked Answered
P

2

6

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);
    }

}
Panek answered 16/12, 2016 at 6:17 Comment(2)
Post your full stack trace and the code which throws this error.Coactive
I put my stack trace and the code, it gives me error at return InitScanner(strDBPath, dbPathTemp), Please help mePanek
C
2

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.

Coactive answered 16/12, 2016 at 7:33 Comment(3)
Sure the .so is in the apk file correctly? And for the correct chipset? The error you posted means it isn't finding the function.Coactive
I put full stack track, but the same code of SignatureLib class and c++ are working in existing product, so where i go wrongPanek
@FaheemRaza, were you able to solve the problem? Please share as I am facing similar one.Gravesend
P
1

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.

Pasture answered 14/3, 2018 at 20:55 Comment(3)
This is not an answer to the question, and you don't have to do any of this: just include the .h file in the .cpp file. Please lay off the SCREAMING BOLDFACE.Vtarj
Hi EJP here is the sample git github.com/NavalKishor/PrimeNumberUsingNdk you just comment the extern "C" in the src/main/../cpp/native-lib in the git and compile you will get the same error java.lang.UnsatisfiedLinkError: No implementation found for and (tried this ... and this...) then you find answer justificable do the needfulPasture
@EJP have you tested the above mentioned casePasture

© 2022 - 2024 — McMap. All rights reserved.