如何使JNI应用程序在Linux上支持多个版本的JVM



我有一个JNI应用程序,它是在使用Java 6的Linux机器上编译的。当我试图在安装了Java 7的机器上运行它时,我会得到以下错误:

/测试:加载共享库时出错:libjvm.so:无法打开共享对象文件:没有这样的文件或目录

问题是libjvm.so位于第二台机器的/usr/lib/jvm/java-7-openjdk-amd64/jre/lib/amd64/server中,而此目录不在RPATH:中

$ objdump -x test | grep RPATH
  RPATH                /usr/lib/jvm/java-6-openjdk/jre/lib/amd64:/usr/lib/jvm/ja
  va-6-openjdk/jre/lib/amd64/server

一个显而易见的解决方案是将/usr/lib/jvm/java-7-openjdk-amd64/jre/lib/amd64/server添加到RPATH,但我想知道是否有更通用的方法来解决这个问题,并使应用程序与系统上安装的任何JVM一起工作?

您可以指定库路径:

java -Djava.library.path="path_here"

编辑:请注意,它需要查找的是文件夹,而不是特定的文件。:)

Edit2:路径可以是相对的。

在Windows上,您可以使用注册表项。但你的问题是关于Linux的,你在那里的选择是有限的。你总是可以使用肮脏的技巧,比如在$PATH上找到java可执行文件,但最干净的方法是$JAVA_HOME。它不像Windows注册表项那样万无一失,因为用户仍然需要手动创建它。但是$JAVA_HOME基本上已经成为查找JVM的标准解决方案。许多其他软件产品都依赖它,所以很可能你的用户已经拥有了它。

我发现了一个在所有基于Debian的发行版上都能很好地工作的解决方案,包括Debian本身、Ubuntu、Mint等:在RPATH中使用/usr/lib/jvm/default-java/...而不是/usr/lib/jvm/java-6-openjdk/...。类似地,对于Centos/RHEL支持,也可以添加/usr/lib/jvm/java/...

作为后备解决方案,可以使用JAVA_HOME或查找java可执行文件的位置。