21

I'm trying to use PJSIP library for my Android application. I built pjsua sample application according to this manual: https://trac.pjsip.org/repos/wiki/Getting-Started/Android

But when sample application is launching, exception triggers:

12-06 15:03:58.043: D/dalvikvm(628): Trying to load lib /data/data/org.pjsip.pjsua2.app/lib/libpjsua2.so 0x4129d980
12-06 15:03:58.064: W/dalvikvm(628): Exception Ljava/lang/UnsatisfiedLinkError; thrown while initializing Lorg/pjsip/pjsua2/app/MyApp;
12-06 15:03:58.064: D/AndroidRuntime(628): Shutting down VM
12-06 15:03:58.064: W/dalvikvm(628): threadid=1: thread exiting with uncaught exception (group=0x409c01f8)
12-06 15:03:58.083: E/AndroidRuntime(628): FATAL EXCEPTION: main
12-06 15:03:58.083: E/AndroidRuntime(628): java.lang.ExceptionInInitializerError
12-06 15:03:58.083: E/AndroidRuntime(628):  at org.pjsip.pjsua2.app.MainActivity.onCreate(MainActivity.java:85)
12-06 15:03:58.083: E/AndroidRuntime(628):  at android.app.Activity.performCreate(Activity.java:4465)
12-06 15:03:58.083: E/AndroidRuntime(628):  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1049)
12-06 15:03:58.083: E/AndroidRuntime(628):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1920)
12-06 15:03:58.083: E/AndroidRuntime(628):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1981)
12-06 15:03:58.083: E/AndroidRuntime(628):  at android.app.ActivityThread.access$600(ActivityThread.java:123)
12-06 15:03:58.083: E/AndroidRuntime(628):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1147)
12-06 15:03:58.083: E/AndroidRuntime(628):  at android.os.Handler.dispatchMessage(Handler.java:99)
12-06 15:03:58.083: E/AndroidRuntime(628):  at android.os.Looper.loop(Looper.java:137)
12-06 15:03:58.083: E/AndroidRuntime(628):  at android.app.ActivityThread.main(ActivityThread.java:4424)
12-06 15:03:58.083: E/AndroidRuntime(628):  at java.lang.reflect.Method.invokeNative(Native Method)
12-06 15:03:58.083: E/AndroidRuntime(628):  at java.lang.reflect.Method.invoke(Method.java:511)
12-06 15:03:58.083: E/AndroidRuntime(628):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
12-06 15:03:58.083: E/AndroidRuntime(628):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
12-06 15:03:58.083: E/AndroidRuntime(628):  at dalvik.system.NativeStart.main(Native Method)
12-06 15:03:58.083: E/AndroidRuntime(628): Caused by: java.lang.UnsatisfiedLinkError: Cannot load library: reloc_library[1285]:    37 cannot locate 'rand'...
12-06 15:03:58.083: E/AndroidRuntime(628):  at java.lang.Runtime.loadLibrary(Runtime.java:370)
12-06 15:03:58.083: E/AndroidRuntime(628):  at java.lang.System.loadLibrary(System.java:535)
12-06 15:03:58.083: E/AndroidRuntime(628):  at org.pjsip.pjsua2.app.MyApp.<clinit>(MyApp.java:235)

It seems like appl cannot load libpjsua2.so library. I have never used the NDK before, so i don't have any ideas about this issue, please help me...

jww
  • 97,681
  • 90
  • 411
  • 885
Anton Galkin
  • 353
  • 1
  • 2
  • 12
  • Possible duplicate of [how to use mkfifo using Android's NDK](http://stackoverflow.com/questions/27091001/how-to-use-mkfifo-using-androids-ndk). – jww Dec 07 '14 at 06:37
  • [Weak symbols](http://en.wikipedia.org/wiki/Weak_symbol) should be able to resolve this issue. But I'm not convinced they work on Android, even though Android defines `__GXX_WEAK__` in the preprocessor. See [Different behavior of override weak function in shared library between OS X and Android](http://stackoverflow.com/q/20196368/608639) and [Does Android support weak symbols?](http://stackoverflow.com/q/27935228/608639). – jww Jan 14 '15 at 05:05

3 Answers3

30

This happens if you've built your native components with the android-21 target, but are trying to run it on a device with an older Android version. Unless you take very special care, you can't run binaries built with the android-21 target on older devices. For basic C functions, it shouldn't matter which target version between android-3 and android-20 you use, it should work on all of them, but if you use android-21 it only works on that version and newer.

See https://stackoverflow.com/a/27093163/3115956 for more details on this issue.

Community
  • 1
  • 1
mstorsjo
  • 12,983
  • 2
  • 39
  • 62
  • "For basic C functions it shouldn't matter..." That's mostly true, but a lot if functions used to be defined as inline and we've promoted them to proper symbols now. Don't have a complete list on hand, but iirc `rand` was one of them. – Dan Albert Dec 07 '14 at 02:08
  • Yes, my comment meant that the normal C functions that indeed did change in android-21, hasn't had any changes between android-3 and android-20. So you can easily build using the android-20 (or android-9) headers e.g. if you want to have a conditionally used codepath that uses OpenSL ES (loaded dynamically using dlsym, or built into a separate .so) while still being able to run on android-3. – mstorsjo Dec 07 '14 at 10:43
  • Android sample application for PJSIP has target SDK version 15 and I'm trying to launch on AVD emulator with API level 15. So it is not root cause. – Anton Galkin Dec 07 '14 at 11:46
  • Are you sure the complete library has been built with target SDK 15, including the native parts (see project.properties, default.properties and jni/Application.mk), not only the frontend sample application itself? – mstorsjo Dec 07 '14 at 13:07
  • oh... Yes you're right! Issue was in android platform version. project.properties and jni/Application.mk were correct, BUT configure-android script sets android-21 version by default. So pjsip was built with android-21 platform version. – Anton Galkin Dec 07 '14 at 19:14
  • @AntonGalkin I have the same issue but not found configure-android script sets android-21 version by default. Can you clear this – shailesh Mar 10 '15 at 08:16
  • Please see comment below. You can see it in logs, when run the configure-android script... – Anton Galkin Mar 11 '15 at 09:06
11

mstorsjo answers my question. But i want write one comment: I had correct properties files, but during pjsip building I found following logs:

sip@ubuntu:~/pjsip/trunk$ ./configure-android
configure-android: APP_PLATFORM not specified, using android-21
configure-android: TARGET_ABI not specified, using armeabi

So if you want compile the project on some specific platform version, you have to set APP_PLATFORM parameter for configure-android script.

TARGET_ABI=armeabi-v7a APP_PLATFORM=android-8 ./configure-android --use-ndk-cflags
Anton Galkin
  • 353
  • 1
  • 2
  • 12
4

I have encountered this when using HUAWEI phone with opus and pngquant jni library for android. Finally the solution is that I add rand,srand and atof function implementions in my source file. Then the problem gone.

Solution from https://github.com/cocos2d/cocos2d-x/issues/15234 Try it!

static u_long myNextRandom = 1;

double atof(const char *nptr)

{
    return (strtod(nptr, NULL));
}

int rand(void)
{
    return (int)((myNextRandom = (1103515245 * myNextRandom) + 12345) % ((u_long)RAND_MAX + 1));
}

void srand(u_int seed)
{
    myNextRandom = seed;
}
W. X
  • 129
  • 2
  • 7