Вызов метода общей библиотеки C из Java не может найти определение метода класса

#java #c #jna

#java #c #jna

Вопрос:

Мне нужно позвонить.итак, функции библиотеки из Java в Debian. Я делаю это с помощью этого кода Java / JNA:

 interface MyLib extends Library {
    MyLib INSTANCE = (MyLib) Native.loadLibrary("mylib.so", MyLib.class);
    int fff();
}

// ...

MyLib m = MyLib.INSTANCE;
System.out.println(m.fff());
  

Это мой код на C :

 .h2

class A1
{
   public:
   void f();
};

.cpp2

#include ".h2"

void A1::f()
{
   std::cout << "from A1" << std::endl;
}

.h1
extern "C"
{
   int fff();
}

.cpp1

#include ".h1"
#include ".h2"

int fff()
{
   // A1().f(); // ERROR CODE

   return 38;
}
  

Если КОД ОШИБКИ прокомментирован — все в порядке, Java-вызов C . итак, успешно, я получаю «38». Но если КОД ОШИБКИ раскомментирован, я получаю эту ошибку

 #
# A fatal error has been detected by the Java Runtime Environment:
#
#  SIGSEGV (0xb) at pc=0x000000000005bb66, pid=14991, tid=14992
#
# JRE version: Java(TM) SE Runtime Environment (10.0.2 13) (build 10.0.2 13)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (10.0.2 13, mixed mode, tiered, compressed oops, g1 gc, linux-amd64)
# Problematic frame:
# C  0x000000000005bb66
#
# No core dump will be written. Core dumps have been disabled. To enable core dumping, try "ulimit -c unlimited" before starting Java again
#
# An error report file with more information is saved as:
# /home/devuser/dev/ktv/tlv/hs_err_pid14991.log
#
# If you would like to submit a bug report, please visit:
#   http://bugreport.java.com/bugreport/crash.jsp
# The crash happened outside the Java Virtual Machine in native code.
# See problematic frame for where to report the bug.
#
Aborted
  

Если я помещу определение A1:: f() в заголовок h2 — все по-прежнему в порядке.

Похоже, что Java не может найти A1:: f() определение в файле cpp2. Почему?

Должен ли я создавать всю свою иерархию кода, вызываемую fff() тегом with extern "C" ?

Ну, я нашел эти ошибки в журнале crush:

 Event: 0.300 Thread 0x00007f4338011000 Exception <a 'java/lang/NoSuchMethodError'{0x00000000c5a96018}: method resolution failed> (0x00000000c5a96018) thrown at [/scratch/opt/mach5/mesos/work_dir/slaves/c4ee7e63-1ded-4e8c-9581-ce26f27e3af4-S497/frameworks/1735e8a2-a1db-478c-8104-60c8b0af87dd-01
Event: 0.300 Thread 0x00007f4338011000 Exception <a 'java/lang/NoSuchMethodError'{0x00000000c5a99b40}: java.lang.invoke.DirectMethodHandle$Holder.invokeStaticInit(Ljava/lang/Object;Ljava/lang/Object;JLjava/lang/Object;)Ljava/lang/Object;> (0x00000000c5a99b40) thrown at [/scratch/opt/mach5/meso
Event: 0.301 Thread 0x00007f4338011000 Exception <a 'java/lang/NoSuchMethodError'{0x00000000c5a9fd60}: method resolution failed> (0x00000000c5a9fd60) thrown at [/scratch/opt/mach5/mesos/work_dir/slaves/c4ee7e63-1ded-4e8c-9581-ce26f27e3af4-S497/frameworks/1735e8a2-a1db-478c-8104-60c8b0af87dd-01
Event: 0.302 Thread 0x00007f4338011000 Exception <a 'java/lang/NoSuchMethodError'{0x00000000c5aa3708}: method resolution failed> (0x00000000c5aa3708) thrown at [/scratch/opt/mach5/mesos/work_dir/slaves/c4ee7e63-1ded-4e8c-9581-ce26f27e3af4-S497/frameworks/1735e8a2-a1db-478c-8104-60c8b0af87dd-01
Event: 0.306 Thread 0x00007f4338011000 Exception <a 'java/lang/NoSuchMethodError'{0x00000000c5aadfd0}: java.lang.invoke.DirectMethodHandle$Holder.invokeStatic(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;I)Ljava/lang/Object;> (0x00000000c5aadfd0) thrown at [/scratch/opt/mach5/mesos/wo
Event: 0.306 Thread 0x00007f4338011000 Exception <a 'java/lang/NoSuchMethodError'{0x00000000c5ab1e20}: java.lang.invoke.DirectMethodHandle$Holder.invokeSpecial(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;I)Ljava/lang/Object;> (0x00000000c5ab1e20) thrown at [/scratch
Event: 0.320 Thread 0x00007f4338011000 Exception <a 'java/lang/UnsatisfiedLinkError'{0x00000000c5916378}: mylib.so: undefined symbol: _ZTVN4Json10FastWriterE> (0x00000000c5916378) thrown at [/scratch/opt/mach5/mesos/work_dir/slaves/c4ee7e63-1ded-4e8c-9581-ce26f27e3af
Event: 0.324 Thread 0x00007f4338011000 Exception <a 'java/lang/NoSuchMethodError'{0x00000000c59233d0}: method resolution failed> (0x00000000c59233d0) thrown at [/scratch/opt/mach5/mesos/work_dir/slaves/c4ee7e63-1ded-4e8c-9581-ce26f27e3af4-S497/frameworks/1735e8a2-a1db-478c-8104-60c8b0af87dd-01
Event: 0.327 Thread 0x00007f4338011000 Exception <a 'java/lang/NoSuchMethodError'{0x00000000c592e328}: java.lang.invoke.DirectMethodHandle$Holder.invokeStatic(Ljava/lang/Object;Ljava/lang/Object;)I> (0x00000000c592e328) thrown at [/scratch/opt/mach5/mesos/work_dir/slaves/c4ee7e63-1ded-4e8c-958
Event: 0.330 Thread 0x00007f4338011000 Exception <a 'java/lang/NoSuchMethodError'{0x00000000c593b1f8}: java.lang.Object.of([Ljava/lang/Object;)Ljava/util/stream/Stream;> (0x00000000c593b1f8) thrown at [/scratch/opt/mac
  

Я пытаюсь устранить ошибку od undefined symbol_ZTVN4Json10FastWriterE. У меня есть /usr/lib/libjsoncpp.so.0.6.0, который экспортирует этот метод, но я не могу сказать java получить его 🙂 Есть все мои настройки:

 file /usr/lib/libjsoncpp.so.0.6.0
/usr/lib/libjsoncpp.so.0.6.0: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, BuildID[sha1]=431ec951fde0671c890664dd6f2e18116509a1bc, stripped
...
file mylib.so
mylib.so: ELF 64-bit LSB shared object, x86-64, version 1 (GNU/Linux), dynamically linked, BuildID[sha1]=756a5666d6e1d1ceb1c77be5c70a31d4698f64af, not stripped
...
java --version
java 14.0.2 2020-07-14
Java(TM) SE Runtime Environment (build 14.0.2 12-46)
Java HotSpot(TM) 64-Bit Server VM (build 14.0.2 12-46, mixed mode, sharing)
...
echo $LD_LIBRARY_PATH
/path_to_mylib_dir:/usr/lib
...
run command
java -Djava.library.path=/usr/lib -Djna.library.path=/usr/lib -jar app-1.0-SNAPSHOT.jar
...
.java
static {
System.setProperty("java.library.path", "/path_to_mylib_dir:/usr/lib");
System.setProperty("jna.library.path", "/path_to_mylib_dir:/usr/lib");
}
..
interface MyLib extends Library {
        MyLib INSTANCE = (MyLib) Native.loadLibrary("/path_to_my_lib/mylib.so", MyLib.class);
        int fff();
    }
..
 MyLib m = MyLib.INSTANCE; -- OK
 System.out.println(m.fff());    -- Crash

  

Вывод отладки

  sudo java10 -Djava.library.path=/usr/lib/libjsoncpp.so.0.6.0 -Djna.library.path=/usr/lib/libjsoncpp.so.0.6.0 -Dsun.boot.library.path=/usr/lib/libjsoncpp.so.0.6.0 -Djna.debug_load=true  -jar app-1.0-SNAPSHOT.jar mylib.so
Hello4
java lib path : /usr/lib;/usr/lib/libjsoncpp.so.0.6.0
jna lib path : /usr/lib/libjsoncpp.so.0.6.0
start
Nov 06, 2020 2:44:58 PM com.sun.jna.Native extractFromResourcePath
INFO: Looking in classpath from jdk.internal.loader.ClassLoaders$AppClassLoader@69663380 for /com/sun/jna/linux-x86-64/libjnidispatch.so
Nov 06, 2020 2:44:58 PM com.sun.jna.Native extractFromResourcePath
INFO: Found library resource at jar:file:/app-1.0-SNAPSHOT.jar!/com/sun/jna/linux-x86-64/libjnidispatch.so
Nov 06, 2020 2:44:58 PM com.sun.jna.Native extractFromResourcePath
INFO: Extracting library to /root/.cache/JNA/temp/jna12671529648887219091.tmp
Nov 06, 2020 2:44:58 PM com.sun.jna.NativeLibrary loadLibrary
INFO: Looking for library '/../mylib.so'
Nov 06, 2020 2:44:58 PM com.sun.jna.NativeLibrary loadLibrary
INFO: Adding paths from jna.library.path: /usr/lib/libjsoncpp.so.0.6.0
Nov 06, 2020 2:44:58 PM com.sun.jna.NativeLibrary loadLibrary
INFO: Trying /../mylib.so
Nov 06, 2020 2:44:58 PM com.sun.jna.NativeLibrary loadLibrary
INFO: Loading failed with message: /../mylib.so: undefined symbol: _ZTVN4Json10FastWriterE
Nov 06, 2020 2:44:58 PM com.sun.jna.NativeLibrary loadLibrary
INFO: Adding system paths: [/usr/lib/x86_64-linux-gnu, /lib/x86_64-linux-gnu, /lib64, /usr/lib, /lib, /usr/lib/vmware-tools/lib64/libvmGuestLibJava.so, /usr/lib/vmware-tools/lib32/libvmGuestLibJava.so, /usr/lib/vmware-tools/lib64/libvmGuestLib.so, /usr/lib/vmware-tools/lib32/libvmGuestLib.so, /usr/lib/x86_64-linux-gnu/libfakeroot, /usr/lib/vmware-tools/lib64/libDeployPkg.so, /usr/lib/vmware-tools/lib32/libDeployPkg.so]
Nov 06, 2020 2:44:58 PM com.sun.jna.NativeLibrary loadLibrary
INFO: Trying /../mylib.so
Nov 06, 2020 2:44:58 PM com.sun.jna.NativeLibrary loadLibrary
INFO: Found library '/../mylib.so' at /../mylib.so
#
# A fatal error has been detected by the Java Runtime Environment:
#
#  SIGSEGV (0xb) at pc=0x0000000000212716, pid=28990, tid=28991
#
# JRE version: Java(TM) SE Runtime Environment (10.0.2 13) (build 10.0.2 13)

And nm for jsoncpp lib
nm -D ./libjsoncpp.so.0.6.0 |grep  _ZTVN4Json10FastWriterE
00000000002430a0 V _ZTVN4Json10FastWriterE
  

Комментарии:

1. Пожалуйста, перекомпилируйте вашу библиотеку с помощью символов отладки, чтобы JVM могла показать вам приличный стек вызовов. Только создание fff as extern "C" нормально.

2. Возможно, вы также захотите получить дамп ядра для дальнейшей отладки docs.oracle.com/javase/8/docs/technotes/guides/troubleshoot /…

3. Как вы компилируете mylib.so ?

4. Я добавил новую информацию об ошибке журнала сбоев UnsatisfiedLinkError. Мой LD_LIBRARY_PATH указывает на /usr/lib, но мне это не помогает..

Ответ №1:

Проблема решается путем компиляции c .итак, библиотека с добавлением в cmakelists.txt необходимые статические и общие библиотеки для target_link_libraries для неопределенных символов