UnsatisfiedLinkError when loading shared lib

O

OtisUsenet

Hi,

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:
/dev/cLib.

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.getProperty("java.library.path"));
System.out.println("2: " + System.mapLibraryName("Foo"));
System.out.println("Loading Foo.so");
System.load("/dev/cLib/libFoo.so");
System.out.println("Loaded");
}

This results in:

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

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
extension

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:
/lib/libNoVersion.so.1:
libc.so.6 (GLIBC_2.0) => /lib/tls/libc.so.6
libc.so.6 (GLIBC_2.1.3) => /lib/tls/libc.so.6
/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!
 
T

Timothy Bendfelt

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
these.


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.
 
O

OtisUsenet

Hi Timothy,

Thanks for the advice. Some more stuff inline.

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

I tried that, but that gives me:
Exception in thread "main" java.lang.UnsatisfiedLinkError: init
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
these.

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?
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.

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.
 
J

Jean-Francois Briere

The problem lies with the init() native method (problably the JNI C
signature).

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 ...

Regards
 
O

OtisUsenet

Hi Jean-Francois,

Jean-Francois Briere said:
The problem lies with the init() native method (problably the JNI C
signature).

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

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

It is called from the MyApp constructor.
Also show us its JNI counterpart signature.
Something like:
JNIEXPORT void JNICALL Java_com_example_MyApp_init(JNIEnv * env,
jobject obj) {
...
}

Here it is:

JNIEXPORT jboolean JNICALL
Java_com_example_MyApp_init(
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
*)dictionaryDir)));
setCxErrCode(env, context, ErrCode);

return success;
}
Finally show us the build command line?
gcc ...

Here:

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?

Thanks.
 
G

Gordon Beaton

Here it is:

JNIEXPORT jboolean JNICALL
Java_com_example_MyApp_init(

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
code?

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
 
O

OtisUsenet

Hi,

Jean-Francois Briere said:
What is the output of:
nm -g /dev/cLib/libFoo.so

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?

Thanks.
 
O

OtisUsenet

Hi Gordon,

Gordon said:
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,

Yes, that's the true name of the package and the class. :)
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
code?

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.
What does "nm libFoo.so | grep init" tell you?

$ nm libFoo.so | grep init
0000c02b T Java_com_example_MyApp_init
Unrelated to this problem, you must call ReleaseStringUTFChars() when
you're finished using the pointer returned by GetStringUTFChars().

Thanks, I'll see if I can change that C code.

Thanks.
 
G

Gordon Beaton

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.

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
 
Joined
Nov 18, 2016
Messages
4
Reaction score
0
Hello,

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


-Varsha
 

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. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top