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)
LD_LIBRARY_PATH
to include the directories of the.so
files and/or have you run Java with the-Djava.libary.path
argument? – stdunbar