Hello,
I would like to call a C++ programm out of Java with help of JNI. By the
followed command I created a "shared library":
g++ -shared -o libcalculate.so rechner.cpp
When I create an object from the existing program inside a method of my
class rechner.cpp, and then call the method out of java, a following
error message:
Exception in thread "main" java.lang.UnsatisfiedLinkError:
/home/home12/kahl/six-cvs/six-0.5.2/six/javainterface/libcalculate.so:
/home/home12/kahl/six-cvs/six-0.5.2/six/javainterface/libcalculate.so:
undefined symbol: _ZN9DualBatch13setConnLimitsEjj
at java.lang.ClassLoader$NativeLibrary.load(Native Method)
at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1751)
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1676)
at java.lang.Runtime.loadLibrary0(Runtime.java:822)
at java.lang.System.loadLibrary(System.java:992)
at Calculate.<clinit>(Calculate.java:16)
at DerJavaRechner.main(DerJavaRechner.java:10)
If I do not create such an object, everything is fine.
I already posted my problem in a c++ group (I am not shure if it is a
java or c++ problem).
Thanks for your help.
Ken
Tim - 21 Feb 2006 21:17 GMT
One thing to note about JNI is that although the 'java.library.path'
property can influence the loading of the initial library it does not
influence the loading of dependent libraries. They must be on the system
path or set up with the LD_LIBRARY_PATH environment variable. It can be
annoying if you want to use a set of shared libraries where A.so causes
the loading of B.so and you have them in the directory '.../app/native/'.
Setting java.library.path to '.../app/native' and calling
System.loadLibrary("A") will find a.so but fail to find b.so.
Does ldd find all dependencies?
Did you run nm on libcalculate.so to make sure the symbol is defined? I
have noticed that JNI is more restrictive about loading libraries with
undefined symbols even when they are not used. a library may be called
from C++ just fine yet fail when called/loaded via JNI.
-- Tim
> Hello,
>
[quoted text clipped - 26 lines]
> Thanks for your help.
> Ken
Kenneth Kahl - 22 Feb 2006 15:52 GMT
Thank you very much for your ideas. I could solve the problem. The
command "ldd -d libcalculate.so" on my library gave me the output:
libstdc++.so.5 => /usr/lib/libstdc++.so.5 (0xb7f2d000)
libm.so.6 => /lib/tls/libm.so.6 (0xb7f0a000)
libgcc_s.so.1 => /lib/libgcc_s.so.1 (0xb7f01000)
libc.so.6 => /lib/tls/libc.so.6 (0xb7dcc000)
/lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x80000000)
undefined symbol: _ZN9DualBatch13setConnLimitsEjj (./libcalculate.so)
undefined symbol: _ZN9DualBatch13setSemiLimitsEjj (./libcalculate.so)
undefined symbol: _ZN7Carrier8bitsIn16E (./libcalculate.so)
There are three undefined symbols in the library. The first and the
second of them contain the string "Batch" and the third contains the
string "carrier". In the c++ program that I want to use are the classes
batch.cpp and carrier.cpp. So I created the library in that way:
g++ -shared -o libcalculate.so rechner.cpp batch.cpp carrier.cpp
And now everything works fine.
Ken
> One thing to note about JNI is that although the 'java.library.path'
> property can influence the loading of the initial library it does not
[quoted text clipped - 44 lines]
>>Thanks for your help.
>>Ken