Android JNI fails to successfully load a lib with dlopen - But it used to

0

This is the story of two (actually four) Android devices. Only one is a phone, and not really relevant to the issue.

My JNI works on one, but not on others.

Up until recently, this application and its JNI was working fine. After not needing to make any updates to the application for a year, I reopened it, and now there is a failure.

This JNI code (with a few name changes to obfuscate the project on a public forum):

void * gTheLibrary;
JNIEXPORT int JNICALL Java_com_doamin_ourapp_ourmodule_LoadLib(JNIEnv * env, jobject obj) {
    globalObject = env->NewGlobalRef( obj );
    env->GetJavaVM( &globalJVM );
    if (gTheLibrary != NULL) {
        __android_log_print(ANDROID_LOG_VERBOSE, APPNAME," JNI-> The lib is already loaded\n");
        return 0;
    }
    gTheLibrary = dlopen("./libmyprocess.so", RTLD_NOW);
    if (gTheLibrary == NULL) {
        char buffer[512];
        sprintf(buffer," JNI-> ****  FAILED to load DSO %s \n", dlerror());
        __android_log_print(ANDROID_LOG_VERBOSE, APPNAME,"%s",buffer);
        return -1;
    }
...

The "dlerror()" log entry reports:

"JNI-> ****  FAILED to load DSO dlopen failed: library "./libmyprocess.so" not found"

But the C library is packaged with the APK. So, the C lib module for this JNI is loading. But it's call to "dlopen()" is not finding the DSO.

As I said, this code USED to work on all devices. Until I reopened the project to make some minor changes. And none of them related to the JNI. Just small Java changes.

  • This code works fine in a Kindle Fire, android version 5.0.1
  • This code fails on the "dlopen(...)" On a Samsung Tablet 10.1" Android 6.0.1
  • This code fails on the HTC Desire 530, Android 7.0
  • This code also works fine on an Odroid SBC running Android 4.4

The devices all were set to allow USB debugging, allow apps from unknown sources, etc... Re-iterating, this used to work all all these devices. Now it fails on some of them.

The JNI library, plus the library it is trying to load, have the Application.mk set with "APP_PLATFORM := android-19" so they are consistent. The Libraries are build outside of Android Studio, so that version shouldn't be a factor, but I am using A.S. 2.3.3. I've recompiled everything in an effort to keep things in sync.

I'm guessing this is related to the OS version. But no leads on what/why it's different for compiled C code. And why, on these same OS versions, it worked a year ago. Is there any advice which can be offered to help identify how to get around this?

Thanks in advance.

-Scotty

---- UPDATE -----
Trying things, and not making progress... Using "arm-linux-androideabi-readelf" I see there are 6 "NEEDED" libraries:

0x00000001 (NEEDED)   Shared library: [liblog.so]
0x00000001 (NEEDED)   Shared library: [libandroid.so]
0x00000001 (NEEDED)   Shared library: [libstdc++.so]
0x00000001 (NEEDED)   Shared library: [libc.so]
0x00000001 (NEEDED)   Shared library: [libm.so]
0x00000001 (NEEDED)   Shared library: [libdl.so]

I gutted completely the lib, and rebuilt it. Not even any #includes... It literally is this:

void * Initialize() {
    return 0;
}

It literally shouldn't need any external libraries. And yet I re-ran "arm-linux-androideabi-readelf" and it still lists those same 6 libraries. And when I retest the app, it still fails to load.

As another test, I took those 6 needed libraries from ...\platforms\android-19\arch-arm\usr\lib\ and copied them into the same "libs" folder as the JNI and the library in dlopen(...), and verified that they are all in the APK (by opening it as a zip). But the JNI DSO is still giving me the same failure on "dlopen(...)".

And my mind keeps falling back to the old adage "It was working before" - What is it that changed in the devices? Or some autoupdate in the Studio/NDK?

java
android
c
jni
asked on Stack Overflow May 17, 2018 by SpacemanScott • edited May 17, 2018 by SpacemanScott

1 Answer

0

This was fixed by eliminating the "local" path...

 gTheLibrary = dlopen("libmyprocess.so", RTLD_NOW);

I am not sure why it was in there originally. I assume because 2 years ago it was necessary to specify the local location of the library. Now, however, it is causing the problem. There is no need to include the 6 "Needed" libraries.

answered on Stack Overflow May 17, 2018 by SpacemanScott

User contributions licensed under CC BY-SA 3.0