UnsatisfiedLinkError when loading shared lib

Discussion in 'Java' started by OtisUsenet, Jul 24, 2006.

  1. OtisUsenet

    OtisUsenet Guest


    I have a shared library that I am trying to load, but I'm hitting the
    wall. I was wondering if anyone could help.

    The library (.so) lives in:

    I run my app as:
    java -Djava.library.path=/dev/cLib com.example.MyApp

    I try to load the library from MyApp like this:
    static {
    System.out.println("1: " +
    System.out.println("2: " + System.mapLibraryName("Foo"));
    System.out.println("Loading Foo.so");

    This results in:

    1: /dev/cLib
    2: libFoo.so
    Loading libFoo.so

    Exception in thread "main" java.lang.UnsatisfiedLinkError: init
    at com.example.MyApp.init(Native Method)

    I also tried this:
    System.loadLibrary("libFoo.so"); // also tried without the .so

    That gave me:
    Exception in thread "main" java.lang.UnsatisfiedLinkError: no libFoo.so
    in java.library.path
    at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1682)
    at java.lang.Runtime.loadLibrary0(Runtime.java:822)
    at java.lang.System.loadLibrary(System.java:992)

    If I switch to using just this:
    System.loadLibrary("Foo"); // no lib prefix, no .so extension

    Then I again get:
    Exception in thread "main" java.lang.UnsatisfiedLinkError: init

    Does anyone know what's going on here?
    I've never worked with shared libraries and JNI before, so I'm not even
    sure if this is how things are supposed to work. Is this how I should
    be loading a shared library?

    Also, if this helps (doesn't mean much to me), this is what ldd says
    about my library:

    $ ldd -v /dev/cLib/libFoo.so
    statically linked

    Version information:
    libc.so.6 (GLIBC_2.0) => /lib/tls/libc.so.6
    libc.so.6 (GLIBC_2.1.3) => /lib/tls/libc.so.6
    ld-linux.so.2 (GLIBC_2.1) => /lib/ld-linux.so.2
    ld-linux.so.2 (GLIBC_2.3) => /lib/ld-linux.so.2
    ld-linux.so.2 (GLIBC_PRIVATE) => /lib/ld-linux.so.2
    ld-linux.so.2 (GLIBC_2.0) => /lib/ld-linux.so.2

    Any help would be greatly appreciated.
    Thank you!
    OtisUsenet, Jul 24, 2006
    1. Advertisements

  2. load the library with System.loadLibrary("Foo"); and let the vm
    sort out the libFoo.so.

    Some things to watch for.

    Undefined symbols in the library. I've noticed that JNI will fail to
    load libraries with undefined symbols even if they are not referenced.
    I've had libraries that could be called from C just fine but fail to load
    via JNI due to some overlooked symbol. Use the nm utility to locate

    Dependent libraries. This is not your case since yours is statically
    linked, but if libFoo.so depended on libBar.so in the same directory
    putting that directory in java.library.path would not help. You need to
    put the directory on the system path (LD_LIBRARY_PATH) so that ld can see
    it too.
    Timothy Bendfelt, Jul 24, 2006
    1. Advertisements

  3. OtisUsenet

    OtisUsenet Guest

    Hi Timothy,

    Thanks for the advice. Some more stuff inline.

    I tried that, but that gives me:
    Exception in thread "main" java.lang.UnsatisfiedLinkError: init
    Ah, I think this might be the problem:

    $ nm /dev/cLib/libFoo.so | grep ' U '
    U __ctype_b_loc
    U __fxstat
    U __strtol_internal
    U calloc
    U fclose
    U fgets
    U fileno
    U fopen
    U fprintf
    U fread
    U free
    U fseek
    U fwrite
    U malloc
    U memcpy
    U memset
    U realloc
    U rewind
    U sscanf
    U stderr
    U strcat
    U strcmp
    U strcpy
    U strncat
    U strncmp
    U strncpy

    Unfortunately, I'm really not familiar with this stuff and am not sure
    what exactly this is telling me and what "undefined symbols" really
    means. :(
    The above symbols look like functions from some standard
    IO/string/memory library. Maybe that library needs to be explicitly
    loaded? Or maybe the system can't find that library?
    Thank you for this, I'll keep that in mind although, like you said,
    this looks like a statically linked library.

    Any help about the above would be very welcome.

    Thank you.
    OtisUsenet, Jul 25, 2006
  4. The problem lies with the init() native method (problably the JNI C

    Please show us the Java class native method signature.
    Something like:
    package com.example;
    class MyApp {
    native void init();

    Also show us its JNI counterpart signature.
    Something like:
    JNIEXPORT void JNICALL Java_com_example_MyApp_init(JNIEnv * env,
    jobject obj) {

    Finally show us the build command line?
    gcc ...

    Jean-Francois Briere, Jul 25, 2006
  5. OtisUsenet

    OtisUsenet Guest

    Hi Jean-Francois,

    It looks like this:
    private native boolean init(Context context, String dir);

    It is called from the MyApp constructor.
    Here it is:

    JNIEnv *env,
    jobject obj,
    jobject context,
    jstring jDictionaryDir)
    jboolean isCopy;
    const char *dictionaryDir =
    (*env)->GetStringUTFChars(env, jDictionaryDir, &isCopy);

    jboolean success = (MA_OK == (ErrCode = MaJpInit((char
    setCxErrCode(env, context, ErrCode);

    return success;

    gcc -c -I$JAVA_HOME/include -I $JAVA_HOME/include/linux \
    -I $MAJP_DIR/include com_example_MyApp.c

    ld -shared -o $LIB_DIR/libFoo.so --whole-archive \
    -L $MAJP_DIR/lib/ -lMaJpLinux com_example_MyApp.o

    This doesn't tell me much, but does this point to potential source of
    the error?

    OtisUsenet, Jul 25, 2006
  6. What is the output of:
    nm -g /dev/cLib/libFoo.so
    Jean-Francois Briere, Jul 25, 2006
  7. Does this reflect the true name of the package and the class? It looks
    suspiciously like you copied it from Jean-Francois' example. I.e. is
    there a package declaration in the Java code, did you specify the
    fully qualified classname when you ran javah, and does the symbol name
    in the generated header agree with the actual name in your native

    What does "nm libFoo.so | grep init" tell you?

    Unrelated to this problem, you must call ReleaseStringUTFChars() when
    you're finished using the pointer returned by GetStringUTFChars().

    Gordon Beaton, Jul 25, 2006
  8. OtisUsenet

    OtisUsenet Guest


    It looks like this:

    0000c1e4 T Java_com_example_MyApp_analyze
    0000c610 T Java_com_example_MyApp_finis
    0000c14c T Java_com_example_MyApp_freeBuffer
    0000c08e T Java_com_example_MyApp_getBuffer
    0000c2e8 T Java_com_example_MyApp_getWord
    0000c02b T Java_com_example_MyApp_init
    0000b860 T MaIndex
    0000acc4 T MaJpBufFree
    0000ac68 T MaJpBufInit
    000060c0 T MaJpCodeStatInit
    00007120 T MaJpDetectCode
    0000882c T MaJpFree
    0000a1bc T MaJpGetPosIdMb
    0000a12c T MaJpGetPosIdWc
    0000a09c T MaJpGetPosNameMb
    0000a018 T MaJpGetPosNameWc
    000084e4 T MaJpInit
    000060e4 T MaJpMbToMb
    00006268 T MaJpMbToWc
    0000ae98 T MaJpProcCbMb
    0000ae20 T MaJpProcCbWc
    0000addc T MaJpProcMb
    0000acf8 T MaJpProcWc
    000062f4 T MaJpWcToMb
    000061e0 T MaJpWcToWc
    0000b8bc T MaRindex
    0000b4d8 T MaStrcasecmp
    0000b64c T MaStrcat
    0000b834 T MaStrchr
    0000b738 T MaStrcmp
    0000b7c0 T MaStrcpy
    0000b97c T MaStrcspn
    0000b6ec T MaStrdup
    0000b6cc T MaStrlen
    0000b540 T MaStrncasecmp
    0000b684 T MaStrncat
    0000b780 T MaStrncmp
    0000b7f0 T MaStrncpy
    0000b8ec T MaStrpbrk
    0000b88c T MaStrrchr
    0000b93c T MaStrspn
    0000b9b4 T MaStrstr
    0000b5bc T MaStrtok
    00003ba0 T MjgfBestPathFind
    00004724 T MjgfBufStBufInit
    00004ca4 T MjgfBufStBufInitE
    0000427c T MjgfBufStDicResGet
    0000420c T MjgfBufStDicResIndexGet
    00003e64 T MjgfBufStFree
    0000412c T MjgfBufStInBufGet
    00004050 T MjgfBufStInBufWcGet
    00004044 T MjgfBufStInit
    00004564 T MjgfBufStKataWorkGet
    00004198 T MjgfBufStOffsetGet
    000040b8 T MjgfBufStOffsetWcGet
    00004430 T MjgfBufStOutBufEGet
    000042ec T MjgfBufStOutBufGet
    000046b0 T MjgfBufStPosNameWorkEGet
    00004644 T MjgfBufStPosNameWorkGet
    00004500 T MjgfBufStStrOptEGet
    000043c4 T MjgfBufStStrOptGet
    0000449c T MjgfBufStStrPrimeEGet
    00004358 T MjgfBufStStrPrimeGet
    000045d8 T MjgfBufStTmpWorkGet
    00005468 T MjgfCharTypeInit
    00007490 T MjgfConTableCheck
    00007464 T MjgfConTableFree
    00007334 T MjgfConTableInit
    00007658 T MjgfDicBodyOptCopy
    000074c0 T MjgfDicBodySearchAll
    000082a8 T MjgfDicTableEntryGet
    000082cc T MjgfDicTableFree
    00008250 T MjgfDicTableInit
    00007e88 T MjgfDicTableLoad
    000082c0 T MjgfDicTableNumGet
    00008438 T MjgfErrorInit
    0000918c T MjgfNormConfigTableFree
    00008990 T MjgfNormConfigTableInit
    00008dd8 T MjgfNormNumeral
    000091a4 T MjgfNormWCharAlphaFullToHalf
    000091c4 T MjgfNormWCharKataHalfToFull
    000091b4 T MjgfNormWCharNumFullToHalf
    0000924c T MjgfNormWCharOldToNew
    00009288 T MjgfNormWCharSplKata
    00009210 T MjgfNormWCharSymAlphaFullToHalf
    000091d4 T MjgfNormWCharSymNumFullToHalf
    000095e4 T MjgfParamConfInit
    00009d08 T MjgfPosTableCnfFileRead
    00009b10 T MjgfPosTableDefFileRead
    00009f64 T MjgfPosTableInflectStart
    00009f50 T MjgfPosTableIsStem
    00009fe8 T MjgfPosTablePosAttr
    00009f70 T MjgfPosTablePosId
    00009fc0 T MjgfPosTablePosName
    0000a000 T MjgfPosTableVerbNorm
    0000a250 T MjgfPostProcOutput
    0000a85c T MjgfPreProcStrCpy
    0000ba48 T MjgfUnknownFindPre
    0000bba8 T MjgfUnknownKataReplace
    00005854 T MsfEeucToIeuc
    00005e6c T MsfIeucToEeuc
    00005eec T MsfIeucToSjis
    00005f98 T MsfIeucToUnicode2
    00006000 T MsfIeucToUnicode8
    00005a60 T MsfSjisToIeuc
    00005be0 T MsfUnicode2ToIeuc
    00005c60 T MsfUnicode8ToIeuc
    000645cc B SmjErrCode
    0000e2a0 A _DYNAMIC
    0000e318 A _GLOBAL_OFFSET_TABLE_
    000504cc A __bss_start
    U __ctype_b_loc
    U __fxstat
    U __strtol_internal
    000504cc A _edata
    00084638 A _end
    000645e0 B aMjgvCharTypeTable
    U calloc
    000504b4 D cxBufAddrName
    000504c0 D cxCurrWordName
    000504c8 D cxDebugName
    000504c4 D cxErrCodeName
    000504bc D cxNumWordsName
    000504b8 D cxWordsAddrName
    U fclose
    U fgets
    U fileno
    U fopen
    000845e0 B fpMjgvError
    U fprintf
    U fread
    U free
    U fseek
    U fwrite
    0000bdd7 T getContextBoolean
    0000be3a T getContextInt
    0000be9a T getCxBufAddr
    0000bdb8 T getDebugMA
    0004f3b4 D iMjgvInitCount
    U malloc
    U memcpy
    U memset
    U realloc
    U rewind
    0000bf38 T setClassInt
    0000bf7d T setClassShort
    0000bfcb T setClassString
    0000beb9 T setContextInt
    0000bf19 T setCxErrCode
    U sscanf
    00084600 B stMjgvParamConf
    U stderr
    U strcat
    U strcmp
    U strcpy
    U strncat
    U strncmp
    U strncpy

    Does that help?

    OtisUsenet, Jul 25, 2006
  9. OtisUsenet

    OtisUsenet Guest

    Hi Gordon,

    Yes, that's the true name of the package and the class. :)
    I didn't build this, I'm really just trying to use it from my java app.
    I know the shared library normally works, it's used in a production
    system, but I don't know how exactly it is used and whether there are
    some dependencies that my system just doesn't satisfy or at least it
    doesn't find them.
    $ nm libFoo.so | grep init
    0000c02b T Java_com_example_MyApp_init
    Thanks, I'll see if I can change that C code.

    OtisUsenet, Jul 25, 2006
  10. If you are on an elf system (like Linux), you can use readelf -d to
    see what other libraries libFoo.so depends on. Look for NEEDED
    entries. On other systems you can use ldd or objdump -p or similar
    tool to see the same information.

    If the library was built with dependencies on other libraries, they
    will either be resolved recursively when the library is loaded or the
    load will fail. Those other libraries must be found by the system
    dynamic linker (e.g. ld.so) which looks in some standard places, some
    configurable places, and in the places mentioned in your
    LD_LIBRARY_PATH (see your system documentation).

    However since your UnsatisfiedLinkError occurs when you attempt to
    invoke the method, that seems to indicate that the method needed by
    the JVM is missing from the library. That could mean that the symbol
    does not have the expected name or that its name was mangled in some
    way by the compiler.

    Gordon Beaton, Jul 25, 2006
  11. OtisUsenet


    Nov 18, 2016
    Likes Received:

    I am also facing similar issue .

    Trying to migrate application from JBoss to tomcat8 .
    We are using a .so native lib for a specific functionality .

    Everytime this function is called we need to load .so file but it throws error :
    Native code library failed to load. java.lang.UnsatisfiedLinkError:

    I have tried multiple things
    1. set -Djava.library.path = XX folder path of native lib explicitly through tomcat VM argument
    2. copy xxx.so file to /usr/lib/ folder and give the -Djava.library.path= /usr/lib
    3. Also tried installing tomcat-APR and tomcat-Native libraries
    4. Tried to Load file using below line to check where native lib is getting loaded or not
    System.loadLibrary(so filename );

    5.Tried settign export LD_LIBRARY_PATH=/usr/local/apr/lib

    But NO LUCK :(:(

    Please someone help with this .
    Why my xxx.so file is not getting loaded

    varshasavant2002, Nov 18, 2016
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.