30

So far I've learned the following about the java.library.path property:

  • It's used when loading native libraries, as opposed to java classes
  • Its default value depends on the operating system:
    • On Windows, it maps to PATH
    • On Linux, it maps to LD_LIBRARY_PATH
    • On OS X, it maps to DYLD_LIBRARY_PATH

(Please correct me if I've misunderstood any of the above)

My motivation:

I want to modify the value of java.library.path seen by a Java application from the framework I've set up to invoke the Java application. I want to do this not by setting the java.library.path property directly, but instead by modifying the system path variable that it maps to. I'd like a clean way to do this that doesn't have ugly OS-specific code or leave out edge cases if possible.

My question:

Is there a way to ask the local Java implementation what environment variable java.library.path maps to?

Then, in a shell script, I'd be able to write something along the lines of:

path_var = get_library_path_variable  # the magic function I want to call
${path_var} = /my/custom/path:${${path_var}}
4

2 回答 2

22

这不是一个完全不合理的问题,但没有好的答案,所以为了后人,我会尝试解释为什么你被卡住了,为什么它不起作用。

  1. java.library.path根本不保证从环境变量中设置。您可以指定您希望它与-Djava.library.path=. 无论如何,这很可能是您真正想做的事情。这就是存在该选项的原因。

  2. 事实证明(至少在 Windows 上),您正在寻找的环境变量不仅仅是不受干扰地使用。试试这个代码。

    package com.stackoverflow;
    
    import java.util.Map;
    
    public class LibPathFinder {
        public static void main(String[] args) {
            String javaLibPath = System.getProperty("java.library.path");
            Map<String, String> envVars = System.getenv();
            System.out.println(envVars.get("Path"));
            System.out.println(javaLibPath);
            for (String var : envVars.keySet()) {
                System.err.println("examining " + var);
                if (envVars.get(var).equals(javaLibPath)) {
                    System.out.println(var);
                }
            }
        }
    }
    

    您会注意到,当它运行时,它打印的前两件事是不同的。如果 Java 正在使用 windowsPATH变量,那么它首先会摆弄该值。我放弃了调查到底发生了什么。关键是,没有一个环境变量与java.library.path. 我没有在 Linux 或 OSX 上尝试过,你的情况可能会有所不同

  3. 像这样弄乱别人的环境变量真的不是很好。它们用于整个外壳程序,因此您承诺您的用户在他们的环境中拥有您的共享库,但只是有时. 改变的唯一真正原因java.library.path是添加本机库。如果您使用的是本机库,那么您已经拥有特定于操作系统的代码(它必须为平台编译,对吗?),所以您真的已经放弃了“没有特定于平台的边缘情况”的斗争。最好的办法是将您的本机库放在系统路径(无论可能是什么)已经找到它的地方,或者将您的库的路径永久添加到它与某种安装程序。如果您不想做任何这些事情,那么我建议使用@malat 代码的变体,打印 real java.library.path,然后将路径附加到脚本中的结果,然后使用-D选项设置它用于真正的程序运行。

于 2013-12-13T16:04:16.540 回答
13

在我的 linux 机器上,这是我要做的:

$ cat GetSystemProperty.java
import java.util.Properties;
import java.util.Enumeration;

public class GetSystemProperty {
  public static void main(String args[]) {
    if( args.length == 0 ) {
      Properties p = System.getProperties();
      Enumeration keys = p.keys();
      while (keys.hasMoreElements()) {
        String key = (String)keys.nextElement();
        String value = (String)p.get(key);
        System.out.println(key + " : " + value);
      }
    }
    else {
      for (String key: args) {
        System.out.println(System.getProperty( key ));
      }
    }
  }
}
$ javac GetSystemProperty.java
$ java GetSystemProperty java.library.path
/usr/lib/jvm/java-6-openjdk/jre/lib/amd64/server:/usr/lib/jvm/java-6-openjdk/jre/lib/amd64:/usr/lib/jvm/java-6-openjdk/jre/../lib/amd64:/usr/java/packages/lib/amd64:/usr/lib/jni:/lib:/usr/lib
于 2013-12-10T15:12:27.720 回答