【问题标题】:System.loadLibrary failing on java 1.6 but working on java 1.5System.loadLibrary 在 java 1.6 上失败,但在 java 1.5 上工作
【发布时间】:2011-10-05 09:44:33
【问题描述】:

我在 AIX 6.1 和 SLES 11 上遇到了一个特殊问题。我正在尝试使用System.loadLibrary() 调用在Java 中加载so 文件。以下是示例程序:

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() - 无效

知道我做错了什么吗?

【问题讨论】:

  • 当你用 1.5 编译它但用 1.6 运行它时会发生什么?
  • 您是否查看了 UnsatisfiedLinkError 的消息?它应该给出一些关于出了什么问题的提示。也许该库已找到,但 Java 6 无法加载。
  • SLES下ldd libSample.so的结果是什么?我猜 AIX 中没有 ldd 。一个可能的原因是 libSample.so 依赖于 JSE 1.5 库。
  • dump -Tv libSample.so 将显示其依赖项和搜索路径。
  • gxx_personality 对 gcc/g++ 东西的尖叫。你的共享库是用 gcc 构建的吗?

标签: java java-native-interface aix


【解决方案1】:

我认为您在使用 JNI 时不应该使用“.so”扩展名。试试System.loadLibrary("libSample");

【讨论】:

  • 嗨,吉姆,我试过了,但运气不好,它仍然说 UnsatisfiedLinkError
  • 这已经很晚了,但对于任何阅读本文的人来说。您必须使用loadLibrary 的平台名称,即在这种情况下它应该是Sample。如果您运行的是 linux,该函数将添加 lib 和 ´.so`,如果您运行的是 windows,该函数将添加 .dll
【解决方案2】:

只是为了扩展 Jim 所说的内容:您不需要 .so 扩展名或文件的“lib”部分。这应该有效(至少,它在 1.6 中适用于我):

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

【讨论】:

  • 嗨 rm5248,也试过这个,但对我没用。我在 AIX 6.1 上。但是同一段代码适用于 java 1.5 版本。它不适用于 1.6 版本的 java。
【解决方案3】:

我想到的前三件事:

  1. 确保该库位于 java lib 路径上(您已完成此操作)
  2. 确保您正确使用System.loadLibrary()。如果您的库名为“libSample.so”,则调用应为System.loadLibrary("Sample")。 (这已在其他答案中提出)
  3. 请考虑 OpenJDK 下的库可能存在问题,这就是您使用的 Java VM。运行命令java -version,如果部分响应类似于OpenJDK Runtime Environment (build 1.6.0_0-b11),请尝试安装官方的Sun JDK,看看是否有效。

【讨论】:

  • 你好 Rob,我使用的是官方的 sun jdk,
  • # /usr/java6/bin/java -version java version "1.6.0" Java(TM) SE Runtime Environment (build pap3260-20071123_01) IBM J9 VM (build 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
【解决方案4】:

另一种可能性是您在 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。

【讨论】:

    猜你喜欢
    • 2012-02-16
    • 2019-01-20
    • 1970-01-01
    • 2013-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-02
    相关资源
    最近更新 更多