【问题标题】:Best way to set environment variables for java program?为java程序设置环境变量的最佳方法?
【发布时间】:2014-10-04 14:33:26
【问题描述】:

我正在编写一个使用 RJava 接口 (http://rforge.net/rJava/) 的 Java 程序。因为这允许在 Java 程序中使用 R,所以我必须确保在用户尝试运行该程序时设置了正确的环境变量。

我的问题是,设置这些变量的最佳方法是什么?我应该在程序执行之前编写一个脚本来设置它们吗?问题是,我必须询问用户 R 安装在哪个目录以及他们的 R 库存储在哪里,因为用户真的可以把它放在任何地方。我认为没有办法解决这个问题,因为我需要使用该信息更新 PATH 变量,以使 RJava 正常工作并能够在我的程序中运行 R 及其库。

我很紧张为用户永久修改 PATH 变量,但我猜其他程序的安装程序一直在这样做......

关于使所有这些工作顺利进行的最佳方式有什么建议吗?

【问题讨论】:

  • 修改环境变量只会影响以修改器为根的进程树。您不会影响启动该进程的 shell 或用户会话中的任何其他内容。

标签: java r command-line environment-variables


【解决方案1】:

你可以在启动java时使用-D选项传入“系统属性”。

java -DLIBRARY_PATH="C:\\SomePath\\" ClassName

这可能比使用环境变量更适合您的情况。

【讨论】:

    【解决方案2】:

    使用一个 java 程序询问用户 R 的安装位置,然后使用 ProcessBuilder 设置一个新的进程环境(包括 R 安装位置,并修改 PATH)并启动第二个使用 RJava 接口的程序。

    这样您就不会永久更改 PATH,而只是针对已启动的第二个程序。 启动器程序可以记住位置,以使用户不必每次都输入它。

    public class Launcher {
    
      public static void main(String[] args) throws Exception {
        String userdir = System.getProperty("user.dir", ".");
        File propertyFile = new File(userdir, "app.properties");
    
        Properties properties = new Properties();
        try (FileInputStream in = new FileInputStream(propertyFile)) {
          properties.load(in);
        }
        catch (FileNotFoundException e) {
          // ok
        }
    
        String location= properties.getProperty("LOCATION", "default");
        System.out.println("Enter Location [" + location+ "]:");
    
        String string = null;
        try (Reader reader = new InputStreamReader(System.in);
            BufferedReader in = new BufferedReader(reader)) {
          string = in.readLine();
        }
    
        if ((string != null) && (string.length() > 0)) {
          location = string;
          properties.setProperty("LOCATION", location);
          OutputStream out = new FileOutputStream(propertyFile);
          properties.store(out, "Application properties");
        }
    
        String classpath = System.getProperty("java.class.path");
        ProcessBuilder pb = new ProcessBuilder();
        pb.command("java", "-cp", classpath, App.class.getName());
        Map<String, String> env = pb.environment();
        env.put("LOCATION", location;
        Process process = pb.start();
    
        try (
            InputStream is = process.getInputStream();
            InputStreamReader isr = new InputStreamReader(is);
            BufferedReader br = new BufferedReader(isr)) {
          String line;
          while ((line = br.readLine()) != null) {
            System.out.println(line);
          }
        }
    
        int exitValue = process.waitFor();
        System.out.println("exit value = " + exitValue);
      }
    }
    
    public class App {
    
      public static void main(String[] args) {
        System.out.println("App: Location: " + System.getenv("LOCATION"));
        System.exit(3);
      }
    }
    

    【讨论】:

    • 对,所以我正在考虑做这样的事情,但这不会要求用户每次想要运行程序时都输入这个吗?我觉得那样会变得相当烦人。我的意思是,我可以将值存储在文件或其他东西中,并可以选择在第二个程序中更改它们,并且只有在该文件不存在或其他什么情况下才运行第一个?我不知道。
    猜你喜欢
    • 1970-01-01
    • 2015-03-23
    • 2014-02-15
    • 1970-01-01
    • 1970-01-01
    • 2021-11-04
    • 1970-01-01
    • 2018-12-29
    • 2016-02-03
    相关资源
    最近更新 更多