System.loadLibrary не работает с java 1.6, но работает с java 1.5

Я столкнулся со своеобразной проблемой в AIX 6.1 и SLES 11. Я пытаюсь загрузить файл so в Java, используя вызов System.loadLibrary(). Ниже пример программы:

public class jniTest
{ 

  public static void main(String[] args)
  {

      try
      {
         System.loadLibrary("libSample.so");
         System.out.println("Loaded!!!");
      }
      catch(UnsatisfiedLinkError e)
      {
         System.out.println("unsatisfiedlinkerror");
      }
}  

Когда я компилирую этот фрагмент кода с помощью Java 1.5, он работает правильно. Но когда я компилирую его с Java 1.6, он говорит UnsatisfiedLinkError. Я не понимаю, как я мог получить эту ошибку. Я бегаю так:

javac jniTest.java

java -Djava.library.path=. jniTest

Файл so находится в текущем каталоге, из которого я запускаю код. До этого я пробовал:

  1. указание абсолютного пути - не сработало

  2. используя Runtime.getRuntime().loadLibrary() - не сработало

Любая идея, что я делаю неправильно?


person manjiler    schedule 14.07.2011    source источник
comment
Что произойдет, если вы скомпилируете его с 1.5, но запустите с 1.6?   -  person phlogratos    schedule 14.07.2011
comment
Вы проверили сообщение об ошибке UnsatisfiedLinkError? Это должно дать некоторый намек на то, что пошло не так. Возможно, библиотека найдена, но не может быть загружена Java 6.   -  person Thomas    schedule 14.07.2011
comment
Каков результат ldd libSample.so под SLES? Я предполагаю, что в AIX нет ldd. Возможная причина заключается в том, что libSample.so имеет зависимость от библиотеки JSE 1.5.   -  person phlogratos    schedule 14.07.2011
comment
dump -Tv libSample.so покажет свои зависимости и путь поиска.   -  person CoreyStup    schedule 14.07.2011
comment
попробовал ldd libSample.so на AIX, я получил это как вывод   -  person manjiler    schedule 15.07.2011
comment
‹p› /usr/lib/libc_r.a(shr.o) /unix /usr/lib/libcrypt.a(shr.o) /usr/lib/libc.a(shr.o) /usr/lib/libcfg .a(shr.o) /usr/lib/libodm.a(shr.o)   -  person manjiler    schedule 15.07.2011
comment
@CoreyStup: хорошая команда, показала все внешние зависимости. Но есть несколько неразрешенных зависимостей. [49] 0x00000000 undef IMP DS EXTref .. _ZdlPv [50] 0x00000000 undef IMP DS EXTref .. _Znam [52] 0x00000000 undef IMP PR EXTref .. __gxx_personality_v0 Что означают эти ссылки? Нигде в коде я не использую ничего подобного... :(   -  person manjiler    schedule 15.07.2011
comment
gxx_personality кричит о вещах gcc/g++. Была ли ваша общая библиотека собрана с помощью gcc?   -  person CoreyStup    schedule 16.07.2011


Ответы (4)


Я не думаю, что у вас должно быть расширение «.so» при использовании JNI. Попробуйте только System.loadLibrary("libSample");

person Jim    schedule 14.07.2011
comment
Привет, Джим, я попробовал, но не повезло, он все еще говорит UnsatisfiedLinkError - person manjiler; 14.07.2011
comment
Это поздно, но для тех, кто читает это. Вы должны использовать название платформы для loadLibrary, т.е. в этом случае это должно быть Sample. Функция добавит lib и «.so», если вы используете Linux, или .dll, если вы используете Windows. - person Emily L.; 21.01.2016

Просто чтобы расширить то, что сказал Джим: вам не нужно расширение .so или часть файла «lib». Это должно работать (по крайней мере, это работает для меня в 1.6):

  try
  {
     System.loadLibrary("Sample");
     System.out.println("Loaded!!!");
  }
  catch(UnsatisfiedLinkError e)
  {
     System.out.println("unsatisfiedlinkerror");
  }
person rm5248    schedule 14.07.2011
comment
Привет rm5248, пробовал и этот, но у меня не сработало. Я на AIX 6.1. Но тот же фрагмент кода работал для версии java 1.5. Это не работает для версии 1.6 java. - person manjiler; 14.07.2011

Первые три вещи, о которых я думаю:

  1. Убедитесь, что библиотека находится на пути java lib (вы сделали это)
  2. Убедитесь, что вы правильно используете System.loadLibrary(). Если ваша библиотека называется "libSample.so", вызов должен быть System.loadLibrary("Sample"). (Это было предложено в других ответах)
  3. Учтите, что может возникнуть проблема с библиотекой в ​​OpenJDK, и это используемая вами виртуальная машина Java. Запустите команду java -version, и если часть ответа похожа на OpenJDK Runtime Environment (build 1.6.0_0-b11), попробуйте установить официальный пакет Sun JDK и посмотрите, работает ли он.
person Rob Heiser    schedule 14.07.2011
comment
Привет Роб, я использую официальный Sun JDK, - person manjiler; 15.07.2011
comment
# /usr/java6/bin/java -version java version 1.6.0 Java(TM) SE Runtime Environment (сборка pap3260-20071123_01) IBM J9 VM (сборка 2.4, J2RE 1.6.0 IBM J9 2.4 AIX ppc-32 jvmap3260-20071121_15015 (JIT включен) J9VM — 20071121_015015_bHdSMR JIT — r9_20071121_1330 GC — 20071031_AA) JCL — 20071118_01 - person manjiler; 15.07.2011

Другая возможность заключается в том, что ваши нативные функции в Java не совпадают с функциями в библиотеке. Существует очень четко определенное соглашение об именах для функций JNI. Например, если у вас есть функция в java, которая должна вызывать библиотечную функцию c/c++:

package my.packagename;

public class Test {

    static {
        System.loadLibrary("Sample");
    }

    public native void testJNI(int arg1);
}

Соответствующая функция в c или c++ ДОЛЖНА быть (при условии, что имя вашего пакета "com.packagename"):

JNIEXPORT void JNICALL Java_my_packagename_Test_testJNI(JNIEnv* env, jobject obj, jint arg1) {
     // ... code here
}

Причина, по которой я прошел через это, заключается в том, что если имена функций не совпадают, выдается UnsatisfiedLinkError.

person Jim    schedule 15.07.2011