简体   繁体   中英

Java JNI “symbol lookup error” when a dependent shared library contains the symbol

On Ubuntu 16.04, I'm building a JNI library against another shared library. The dependency is OpenCv, version 3.4.0, built locally and not installed in a standard library path.

I'm using cmake from maven to build the my JNI library. The output of the compile and link lines are as follows:

[ 66%] Building CXX object CMakeFiles/lib-image-native.jiminger.com.dir/sources/CvRasterNative.cpp.o /usr/bin/c++ -DUNIX -Dlib_image_native_jiminger_com_EXPORTS -I/usr/lib/jvm/java-8-openjdk-amd64/include -I/usr/lib/jvm/java-8-openjdk-amd64/include/linux -I/home/jim/src/opencv-packaging/package-native/target/cmake -I/home/jim/utils/opencv-3.4.0/installed/include -fPIC -std=gnu++11 -o CMakeFiles/lib-image-native.jiminger.com.dir/sources/CvRasterNative.cpp.o -c /home/jim/src/opencv-packaging/package-native/target/sources/sources/CvRasterNative.cpp [100%] Linking CXX shared module liblib-image-native.jiminger.com.so /home/jim/src/opencv-packaging/package-native/target/dependency/cmake/bin/cmake -E cmake_link_script CMakeFiles/lib-image-native.jiminger.com.dir/link.txt --verbose=1 /usr/bin/c++ -fPIC -shared -o liblib-image-native.jiminger.com.so CMakeFiles/lib-image-native.jiminger.com.dir/sources/CvRasterNative.cpp.o -Wl,-rpath,/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/amd64:/usr/lib/jvm/ java-8-openjdk-amd64/jre/lib/amd64/server /usr/lib/jvm/java-8-openjdk-amd64/jre/lib/amd64/libjawt.so /usr/lib/jvm/java-8-openjdk-amd64/jre/lib/amd64/server/libjvm.so

When I run a test that calls my native function I get:

.../java: symbol lookup error: [path to my library].so: undefined symbol: _ZN2cv6String8allocateEm

Inside my java code I'm explicitly loading this library (using System.load) as well as the dependent OpenCv library. That symbol is in the OpenCv library that I'm explicitly System.load'ing.

nm [path to opencv shared library].so | grep _ZN2cv6String8allocateEm

gives

0000000000442990 t _ZN2cv6String8allocateEm

When I call into my library I get that error. It says the symbol is undefined. But it's definition is in the other library (notice, it's in the 'text' segment) which I'm explicitly loading.

Can someone please tell me what I'm missing?

Thanks

EDIT: If it makes a difference, when I ldd my shared library I get

linux-vdso.so.1 =>  (0x00007ffe6e58f000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f7d279dc000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f7d277c5000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f7d273fb000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f7d270f2000)
/lib64/ld-linux-x86-64.so.2 (0x00005574eb402000)

I figured out what the problem was. I didn't realize the output of the nm command shows local (vs externally visible) symbols. From the man page for nm :

The symbol type. At least the following types are used; others are, as well, depending on the object file format. If lowercase, the symbol is usually local; if uppercase, the symbol is global (external).

The symbol in the dependent library is local indicated by the lower case 't'.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM