JNI "character search error" in the Linux shared library

What do you do when the Java VM has a "character search error" when executing a JNI function? The symbol search error is not in the main library of shared objects that supports the JNI, and is not located directly in the library associated with the main library of objects, but in the library associated with the library associated with your shared JNI? (which is an incredibly inconvenient sentence โ˜บ) In particular, what do you do when you do not control the code for a library containing an intruder?

I have a problem using JNI to access the science camera SDK (Andor NEO CMOS). I use the Netbeans C / C ++ plugin on RHEL 6 to create a shared library (AndorC.so), which basically creates JNI wrappers around the methods provided by the SDK cameras. The camera SDK provides a set of camera access methods that are packaged in a shared library of objects (libatcore.so). The libatcore.so library uses a number of additional libraries, libatdevregcam.so (for a real camera), libatdevsimcam.so (for a simulated camera), libatcl_bitflow.so (low-level video card driver), etc.

I tested the camera SDK extensively and I can easily access the camera with C / C ++. I contacted the shared library (AndorC), which implements the JNI functions from the C test program (using a separate header file), and everything works correctly (that is, I can read the image and the program exits normally).

My Java code can execute the "InitializeLibrary" and "FinalizeLibrary" functions from the SDK via the JNI interface, so there is no problem finding the libatcore.so primary library or my AndorC.so library. There seems to be no problem with basic JNI setup. However, when I try to execute the โ€œOpenโ€ function for the camera (that is, a function that actually connects to a real and / or simulated camera), I get an undefined symbol error in one of the libraries that libatcore.so is used at runtime (libdevsimcam.so).

/usr/local/java/jdk1.7.0_03/jre/bin/java: symbol lookup error: /usr/local/lib/libatdevsimcam.so: undefined symbol: _ZN20TAndorLibDebugOutput6OutputEPKciS1_xx24TAndorDebugFunctionLevel16TAndorDebugLevelS1_z Java Result: 127 

Essentially, the Java virtual machine has no problem with libatcore.so (that is, the main library file), and it has no problem finding the associated runtime library (/usr/local/lib/libatdevsimcam.so), but it starts in the undefined character in this library when it tries to open the camera (note that Im actually opens a real camera NOT a simulated camera).

When I checked the dependencies for each of the libraries (libAndorC.so, libatcore.so, libatdevsimcam.so), I did not find undefined characters. Obviously, the undefined symbol in the libatdevsimcam.so library is not a problem when the program starts directly from C / C ++, but it causes a problem when the Java VM tries to load libatdevsimcam.so.

  libAndorC.so linux-vdso.so.1 => (0x00007fff507ff000) libatcore.so.3 => /usr/local/lib/libatcore.so.3 (0x00007fe23a278000) libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x00007fe239f4a000) libm.so.6 => /lib64/libm.so.6 (0x00007fe239cc6000) libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007fe239ab0000) libc.so.6 => /lib64/libc.so.6 (0x00007fe239730000) libpthread.so.0 => /lib64/libpthread.so.0 (0x00007fe239513000) libdl.so.2 => /lib64/libdl.so.2 (0x00007fe23930f000) librt.so.1 => /lib64/librt.so.1 (0x00007fe239106000) /lib64/ld-linux-x86-64.so.2 (0x0000003f07000000) libatcore.so linux-vdso.so.1 => (0x00007fffd53ff000) libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f7e6b645000) libdl.so.2 => /lib64/libdl.so.2 (0x00007f7e6b440000) librt.so.1 => /lib64/librt.so.1 (0x00007f7e6b238000) libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x00007f7e6af31000) libm.so.6 => /lib64/libm.so.6 (0x00007f7e6acac000) libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007f7e6aa96000) libc.so.6 => /lib64/libc.so.6 (0x00007f7e6a717000) /lib64/ld-linux-x86-64.so.2 (0x0000003f07000000) ldd libatdevsimcam.so linux-vdso.so.1 => (0x00007fff247ef000) libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f5219dc4000) libdl.so.2 => /lib64/libdl.so.2 (0x00007f5219bbf000) librt.so.1 => /lib64/librt.so.1 (0x00007f52199b7000) libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x00007f52196b0000) libm.so.6 => /lib64/libm.so.6 (0x00007f521942b000) libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007f5219215000) libc.so.6 => /lib64/libc.so.6 (0x00007f5218e96000) /lib64/ld-linux-x86-64.so.2 (0x0000003f07000000) 

When I specifically test a character, the Java VM has a problem with its clarity, that the character is undefined.

 nm libatdevsimcam.so | grep _ZN20TAndor U _ZN20TAndorLibDebugOutput6OutputEPKciS1_xx24TAndorDebugFunctionLevel16TAndorDebugLevelS1_z 

I thought that perhaps the symbol was not defined in the libatdevsimcam.so version of the debug and debug versions, so I tried to create a version of libAndorC.so, but I have the same problem.

I have two main questions:

  • Could this be a problem when changing a C ++ name? Ive tried to compile my test program with gcc instead of g ++, and I ran into a lot of compilation errors. Ive read that changing a C ++ name can cause problems.

  • Is this a problem in the libatdevsimcam.so library provided by the manufacturer? I cannot control the code provided by Andor to support the camera (all I can do is complain).

Im basically stuck at this point, because all SDK functions require a reference to the camera descriptor returned by the Open method. If I cannot open the camera, I cannot continue to develop the JNI interface for the camera that I need.

I am carefully studying this question, and I did not find answers to them that directly relate to this problem. This is not a standard โ€œunsatisfied linkโ€ error, which is so often found in JNI messages, and the main JNI function works (that is, you can initialize and shut down the library or call any function that does not have direct access to the camera). This is similar to a situation where the Java VM runs into a problem with its own code that simply runs the code directly. How do you deal with this problem? Is this a problem that I have to accept for the manufacturer, or is there a way to configure / compile / link to this?

Additional information:

  • NetBeans development environment 6.9.1
  • JDK 1.7_0_03 64-bit server
  • Compilation of sources as 64-bit (that is, there should be no problems with 32 and 64 bits)
+8
jni
source share
2 answers

You can get rid of it using LD_PRELOAD (but I don't think this is a suitable solution)

Story

I had the same problem and my script ...

* javaHelloWorldApp.java โ†’ JNI_Hello_world.c โ†’ this built-in c function calls the snmp library *

java: symbol lookup error: /home/source/bin/libmytest.so: undefined symbol: init_snmp

I used LD_PRELOAD as shown here and it solves the problem for now. export LD_PRELOAD=/usr/local/lib/libnetsnmp.so.30

Open question

ldd gives (note, no link to snmp library)

ldd ../ libmytest / bin / libmytest.so linux-gate.so.1 => (0xb7777000) libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb75a3000) / lib / ld -linux.so.2 (0xb7778000)

with export LD_PRELOAD=/usr/local/lib/libnetsnmp.so.30 I see links to snmp,

snmp $ ldd ../ libredsnmp / bin / libredsnmp.so

 linux-gate.so.1 => (0xb770c000) /usr/local/lib/libnetsnmp.so.30 (0xb763a000) libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb746c000) librt.so.1 => /lib/i386-linux-gnu/librt.so.1 (0xb7462000) libcrypto.so.1.0.0 => /lib/i386-linux-gnu/libcrypto.so.1.0.0 (0xb72b7000) /lib/ld-linux.so.2 (0xb770d000) libpthread.so.0 => /lib/i386-linux-gnu/libpthread.so.0 (0xb729c000) libdl.so.2 => /lib/i386-linux-gnu/libdl.so.2 (0xb7297000) libz.so.1 => /lib/i386-linux-gnu/libz.so.1 (0xb7281000) 

my compilation line,

gcc -fPIC -shared -o ./bin/libmytest.so -I/usr/lib/jvm/java-6-openjdk-i386/include/ -I/usr/lib/jvm/java-6-openjdk-i386/include/linux -static -lc JNI_Hello_world.c

The other options I tried, -L/usr/local/lib -lnetsnmp , have no effect, so I retired from compilation.

EDIT-1

it worked with these two commands and no other environment variable. First compile the source

 gcc -c -fPIC ./mytest.c -o mytest.o -I$(JAVA_INC_PATH) -I$(JAVA_INC_PATH)linux 

Now, when creating a shared library, use the -rpath linker option.

 gcc -shared -o ./bin/libmytest.so mytest.o -Wl,-rpath,/usr/local/lib -L/usr/local/lib -lnetsnmp 

Detailed description

For a detailed description, refer to this book (or simply this book search book, @ch. 41.10)

+9
source share

I had a similar problem, and later I discovered that this is an order binding problem:

you need to put -L / usr / local / lib -lnetsnmp after -o libmytest.so for it to work.

+3
source share

All Articles