yvesonline
yvesonline

Reputation: 4837

JNI exits with "undefined symbol"

I'm trying to use AES via the Crypto++ package from Java. Therefore I have two native methods encrypt and decrypt in my Java code which are then wrapped by C in order to access the C++ methods. Running my C++ program from the command line works, but calling it from Java via JNI fails with an undefined symbol error:

Exception in thread "main" java.lang.UnsatisfiedLinkError: /home/yves/temp/lib/libCI3CppEncryptionTools.so: /home/yves/temp/lib/libCI3CppEncryptionTools.so: undefined symbol: _ZTIN8CryptoPP6FilterE

I'm compiling it via:

g++ -c -Icryptopp562 -O3 -fwhole-program -fdata-sections -ffunction-sections -fPIC -fpermissive CI3CppEncryptionToolsImpl.cpp -Lcryptopp562 -lcryptopp
gcc -I${JAVA_HOME}/include -O3 -fwhole-program -fdata-sections -ffunction-sections -Wall -shared -fPIC -o libCI3CppEncryptionTools.so CI3CppEncryptionTools.c CI3CppEncryptionToolsImpl.o -Wl,--gc-sections

So first the C++ part and then combined with the C wrapper. -fdata-sections, -ffunction-sections and -Wl,--gc-sections were my attempt to strip dead code because I thought maybe JNI does not like unused or unreferenced code.

I checked if the symbol is undefined by using:

nm lib/libCI3CppEncryptionTools.so | grep _ZTIN8CryptoPP6FilterE
U _ZTIN8CryptoPP6FilterE

And yes, it is. But why is my C++ command line program working? Checking this yields the same result.

I also looked the symbol up:

c++filt _ZTIN8CryptoPP6FilterE
typeinfo for CryptoPP::Filter

The header for CryptoPP::Filter is included. I'm curious why it says U when checking for the symbol.

Does anyone have any idea what could cause the problem or where to look next to solve the problem? Any hints/insights are highly welcome!

Upvotes: 0

Views: 1404

Answers (2)

yvesonline
yvesonline

Reputation: 4837

I always forgot to link the Crypto++ library in the second step (actually I did it in the first step, which was complete nonsense). Those two commands compile the library a-ok!

g++ -c -Icryptopp562 -O3 -fPIC -fpermissive CI3CppEncryptionToolsImpl.cpp
gcc -I${JAVA_HOME}/include -O3 -shared -fPIC -o libCI3CppEncryptionTools.so CI3CppEncryptionTools.c CI3CppEncryptionToolsImpl.o -lcryptopp

Upvotes: 1

Samhain
Samhain

Reputation: 1765

Compile your CI3CppEncryptionTools.c first, then link its .o into the .so. You are linking the .c

Edit: Statically link your cryptocpp library into your shared library via : -Wl,--whole-archive libcryptocpp.a -Wl,--no-whole-archive

gcc -I${JAVA_HOME}/include -O3 -fwhole-program -fdata-sections -ffunction-sections -Wall -shared -fPIC -o libCI3CppEncryptionTools.so CI3CppEncryptionTools.c CI3CppEncryptionToolsImpl.o -Wl,--whole-archive libcryptocpp.a -Wl,--no-whole-archive -Wl,--gc-sections

Upvotes: 1

Related Questions