如何将库解压缩到临时目录,从该目录加载它及其所有依赖项

时间:2011-12-05 20:07:28

标签: java c++ linux shared-libraries

基本上我想压缩jar文件中的共享对象集合,在运行时将它们解压缩到临时目录,然后从那里加载。比方说,我有库:

  • libApp.so
  • libBasicPlugin.so => libApp.so
  • libPlugin1.so => libApp.so,libBasicPlugin.so,libPlugin2.so
  • libPlugin2.so => libApp.so,libBasicPlugin.so

Java将它们解压缩到一个任意的,唯一的临时目录$ USER_HOME / .my-app / 2011_12_05_001 /,然后加载libApp.so,后者又使用dlopen加载libPlugin1和libPlugin2(未明确加载libBasicPlugin)。问题是libPlugin1不知道在哪里可以找到libBasicPlugin和libPlugin2。

以下是我尝试/考虑的各种解决方案:

  1. 在调用Java之前,将库放在已知位置并在sh文件中设置LD_LIBRARY_PATH。这有效,但不能将库打包在罐子里
  2. 使用Java的System.load来“预加载”依赖项。这是我见过的建议的方法,但是如果您事先知道要加载什么插件并知道它们的依赖关系,那么它们似乎才有效。除非您迭代目录中的所有文件,否则加载它们直到您停止获取UnsatisfiedLinkExceptions ...
  3. 以某种方式告诉共享对象它的依赖项将在同一目录中(通过DT_RPATH?)。这是我认为在理想世界中我想要的,但是你可以做的最好是设置相对于可执行文件的库位置,在本例中是/ usr / lib / jvm /.../ java。< / LI>
  4. 将每个库与其依赖项静态链接。我担心这会导致libPlugin2的两个副本(一个动态的和一个静态的),这在过去给我们造成了各种各样的问题。
  5. 在Windows上,在加载插件之前调用SetDllDirectory可以很好地解决这个问题。有没有我忽视的解决方案/误解?我完全错误地采取了这种方式吗?

1 个答案:

答案 0 :(得分:0)

您可以在Java进程本身内设置LD_LIBRARY_PATH env var。