2013-03-31 15 views
5

Tôi muốn tìm đường dẫn JDK trên nhiều hệ điều hành.Tìm đường dẫn JDK và lưu nó dưới dạng một chuỗi trong Java

Tôi không chắc chắn nếu có một cách hay để làm điều này như tôi đã cố gắng và thất bại.

Đối với Windows nó sẽ là một cái gì đó như thế này - C:\Program Files\Java\jdk1.7.0_07 hay này C:\Program Files(x86)\Java\jdk1.7.0_07

Đối với Linux nó sẽ là một cái gì đó như thế này - /usr/java/jdk1.7.0_07

Tôi muốn điều này để làm việc cho bất kỳ phiên bản của JDK cài đặt, do đó các số sau Java \ jdk không liên quan.

tôi sẽ sử dụng System.setProperty("java.home", path);

Về cơ bản, những gì tôi đang tìm cách để làm là khi tôi chạy chương trình, thiết lập java.home tôi để được cài đặt JDK trên máy hiện tại, nhưng việc con đường JDK được chứng minh rất khó khăn, giải pháp nào?

+2

Tại sao bạn cần tìm đường dẫn của JDK? Tôi bối rối là tại sao người ta lại muốn thông tin này. – Makoto

+4

đây là biến môi trường 'JAVA_HOME' dành cho! –

+0

Tôi đang sử dụng nó để biên dịch các lớp khác. Chương trình của tôi, biên dịch các chương trình khác. – Ciphor

Trả lời

7

Bạn có thể tìm đường dẫn JDK bằng cách tìm xem javac đã được cài đặt ở đâu. Giả sử rằng "javac" nằm trong đường dẫn môi trường của hệ thống thì bạn có thể lấy lại con đường bằng cách đi qua "nơi javac" mã như sau

public static String getCommandOutput(String command) { 
    String output = null;  //the string to return 

    Process process = null; 
    BufferedReader reader = null; 
    InputStreamReader streamReader = null; 
    InputStream stream = null; 

    try { 
     process = Runtime.getRuntime().exec(command); 

     //Get stream of the console running the command 
     stream = process.getInputStream(); 
     streamReader = new InputStreamReader(stream); 
     reader = new BufferedReader(streamReader); 

     String currentLine = null; //store current line of output from the cmd 
     StringBuilder commandOutput = new StringBuilder(); //build up the output from cmd 
     while ((currentLine = reader.readLine()) != null) { 
      commandOutput.append(currentLine); 
     } 

     int returnCode = process.waitFor(); 
     if (returnCode == 0) { 
      output = commandOutput.toString(); 
     } 

    } catch (IOException e) { 
     System.err.println("Cannot retrieve output of command"); 
     System.err.println(e); 
     output = null; 
    } catch (InterruptedException e) { 
     System.err.println("Cannot retrieve output of command"); 
     System.err.println(e); 
    } finally { 
     //Close all inputs/readers 

     if (stream != null) { 
      try { 
       stream.close(); 
      } catch (IOException e) { 
       System.err.println("Cannot close stream input! " + e); 
      } 
     } 
     if (streamReader != null) { 
      try { 
       streamReader.close(); 
      } catch (IOException e) { 
       System.err.println("Cannot close stream input reader! " + e); 
      } 
     } 
     if (reader != null) { 
      try { 
       streamReader.close(); 
      } catch (IOException e) { 
       System.err.println("Cannot close stream input reader! " + e); 
      } 
     } 
    } 
    //Return the output from the command - may be null if an error occured 
    return output; 
} 

Chuỗi trả về sẽ là vị trí chính xác của javac để bạn có thể cần thêm chế biến để có được những thư mục đó javac nằm trong bạn sẽ cần phải phân biệt giữa Windows và OS khác

public static void main(String[] args) { 

    //"where" on Windows and "whereis" on Linux/Mac 
    if (System.getProperty("os.name").contains("win") || System.getProperty("os.name").contains("Win")) { 
     String path = getCommandOutput("where javac"); 
     if (path == null || path.isEmpty()) { 
      System.err.println("There may have been an error processing the command or "); 
      System.out.println("JAVAC may not set up to be used from the command line"); 
      System.out.println("Unable to determine the location of the JDK using the command line"); 
     } else { 
      //Response will be the path including "javac.exe" so need to 
      //Get the two directories above that 
      File javacFile = new File(path); 
      File jdkInstallationDir = javacFile.getParentFile().getParentFile(); 
      System.out.println("jdk in use at command line is: " + jdkInstallationDir.getPath()); 
     }//else: path can be found 
    } else { 
     String response = getCommandOutput("whereis javac"); 
     if (response == null) { 
      System.err.println("There may have been an error processing the command or "); 
      System.out.println("JAVAC may not set up to be used from the command line"); 
      System.out.println("Unable to determine the location of the JDK using the command line"); 
     } else { 
      //The response will be "javac: /usr ... " 
      //so parse from the "/" - if no "/" then there was an error with the command 
      int pathStartIndex = response.indexOf('/'); 
      if (pathStartIndex == -1) { 
       System.err.println("There may have been an error processing the command or "); 
       System.out.println("JAVAC may not set up to be used from the command line"); 
       System.out.println("Unable to determine the location of the JDK using the command line"); 
      } else { 
       //Else get the directory that is two above the javac.exe file 
       String path = response.substring(pathStartIndex, response.length()); 
       File javacFile = new File(path); 
       File jdkInstallationDir = javacFile.getParentFile().getParentFile(); 
       System.out.println("jdk in use at command line is: " + jdkInstallationDir.getPath()); 
      }//else: path found 
     }//else: response wasn't null 
    }//else: OS is not windows 
}//end main method 

Lưu ý:. nếu phương thức trả về null/lỗi nó không có nghĩa rằng javac không tồn tại - rất có thể là javac không nằm trong biến môi trường PATH trên các cửa sổ và vì vậy không thể được tìm thấy bằng cách sử dụng phương pháp này. Điều này không có khả năng trên Unix vì Unix thường tự động thêm thư mục jdk/bin vào PATH. Ngoài ra, điều này sẽ trả về phiên bản javac hiện đang được sử dụng tại dòng lệnh, không nhất thiết phải cài đặt phiên bản mới nhất. vì vậy, ví dụ: 7u12 và 7u13 được cài đặt nhưng dấu nhắc lệnh được đặt để sử dụng 7u12 thì đó là đường dẫn sẽ được trả lại.

Chỉ được thử nghiệm trên nhiều máy Windows nhưng hoạt động tốt trên chúng.

Hy vọng điều này hữu ích.

0

System.getProperty ("java.home") không đủ tốt cho bạn?

Nếu kết thúc bằng "jre" bạn sẽ biết đó là jre, bạn có thể thử đi bộ và tìm các thư mục gốc và kiểm tra các tệp riêng biệt chỉ đến với JDK để chắc chắn.

+2

System.getProperty ("java.home") sẽ cho tôi JRE – Ciphor

+0

bạn không thể sử dụng thư mục đó làm điểm xuất phát? đi tới cha mẹ, sau đó kiểm tra các tệp nhất định để xem liệu JRE bạn đang sử dụng có phải là tệp đi kèm với JDK hay không hoặc chỉ đơn giản là JRE – Gubatron

0

Biến JAVA_HOME trong System.getProperties() đề cập đến JRE chứ không phải JDK. Bạn sẽ có thể tìm ra JDK với:

Map<String, String> env = System.getenv(); 
     for (String envName : env.keySet()) 
     { 
      System.out.format("%s=%s%n", 
        envName, 
        env.get(envName)); 
     } 
+0

Danh sách này liệt kê mọi biến môi trường đơn lẻ! Khá tuyệt, nhưng tôi cần một cách để giải nén chỉ một con đường? Bất kỳ ý tưởng? – Ciphor

2

JAVA_HOME là nghĩa vụ để trỏ đến đường dẫn cài đặt JDK và JRE_HOME đến đường dẫn cài đặt JRE trong tất cả các hệ điều hành

+0

Đó là những gì tôi nghĩ là giải pháp chính xác, nhưng [hướng dẫn cài đặt chính thức] (http://docs.oracle.com/javase/7/docs/webnotes/install/windows/jdk-installation-windows.html) không 't nói bất cứ điều gì về 'JAVA_HOME' –

0

Đây là quan điểm của tôi về vấn đề này: Bạn có thể chọn nơi bạn muốn cài đặt jdk và bạn cũng có thể cài đặt nhiều jdk. Vì vậy, tôi không nghĩ rằng có thể có một biến tiêu chuẩn cho việc này.

Cho phép giả định cấu trúc thư mục chuẩn đã được sử dụng để cài đặt jdk. Trong kịch bản này, các cài đặt jre và jdk sẽ nằm trong cùng một thư mục.

Vì vậy, một khi bạn nhận được System.getProperty ("java.home") thì hãy tìm kiếm thư mục đơn giản.

Hy vọng điều đó sẽ hữu ích.

0

Thiên Chúa này rất phức tạp, nhưng tôi đã hoàn thành. Mặc dù nó chỉ có được thử nghiệm trên Windows.

import java.io.File; 

public class Main { 
    public static void main(String[] args) { 
     String JDK_VERSION = "jdk" + System.getProperty("java.version"); // finds the JDK version currently installed 
     String PATH_VARIABLE = System.getenv("PATH"); // finds all the system environment variables 

     // separates all the system variables 
     String[] SYSTEM_VARIABLES = PATH_VARIABLE.split(";"); 

     // this object helps build a string 
     StringBuilder builder = new StringBuilder(); 

     // loop through all the system environment variables 
     for (String item : SYSTEM_VARIABLES) { 
      // if the system variable contains the JDK version get it! (all lower case just to be safe) 
      if (item.toLowerCase().contains(JDK_VERSION.toLowerCase())) { 
       // adds the JDK path to the string builder 
       builder.append(item); 
      } 
     } 

     // stores the JDK path to a variable 
     String result = builder.toString(); 
     // turns the path, which was a string in to a usable file object. 
     File JDK_PATH = new File(result); 
     // since the path is actually in the JDK BIN folder we got to go back 1 directory 
     File JDK_PATH_FINAL = new File(JDK_PATH.getParent()); 
     // prints out the result 
     System.out.println(JDK_PATH_FINAL); 
    } 
} 

Điều cơ bản là lấy tất cả các biến hệ thống và tìm nếu một trong số đó chứa phiên bản java (cách tôi nhận đường dẫn đến JDK). Vì đường dẫn biến hệ thống thực sự nằm trong thư mục bin JDK, nó chuyển đường dẫn JDK String thành một File và quay trở lại một thư mục trong thư mục JDK.

+0

điều này sẽ không làm việc luôn luôn khi cài đặt tôi có thể thay đổi đường dẫn và dấu chấm phẩy không phải là tách tệp cho tất cả các hệ điều hành sử dụng các hằng số – tgkprog

0

Bạn có thể sử dụng hàm getenv của java để lấy PATH.

0

Bạn phải biết lưu trữ JDK ở đâu vì bạn có thể cài đặt nó ở bất kỳ đâu.

Tôi có thể đề nghị somethings như bạn nói:

  • Bạn có thể tìm JAVA_HOME biến hệ thống nó phải như thế này:

Đối với Windows (nếu bạn cài đặt thông qua thiết lập với cấu hình tùy chỉnh);

C:\Program Files\Java\jdk1.6.0_41 
//or 
C:\Program Files(x86)\Java\jdk1.6.0_41 

Đối với Linux (nếu bạn cài đặt qua thiết lập với cấu hình tùy chỉnh);

/usr/java/jdk1.6.0_41 
//or 
/usr/jvm/jdk1.6.0_41 
//or 
/opt/java/jdk1.6.0_41 
  • Nếu bạn muốn thay đổi JAVA_HOME vị trí:

Trên Windows:

You have to change JAVA_HOME variable as manually 

Trên Linux:

You can use "update-java" script by WebUpd8 ([https://code.google.com/p/webupd8/downloads/list][1]) 
0

Tôi nghĩ rằng đặt cược tốt nhất và chắc chắn nhất của bạn (bởi vì Java_home vv không HA VE được tuyên bố để có được một JVM lên, tôi có thể sử dụng đường dẫn đầy đủ trong một kịch bản và khởi động Java.

Lấy id quá trình java, sử dụng API để nhận đường dẫn của quá trình đó.

Đây không phải là giải pháp đầy đủ mà là hướng dẫn cách thực hiện.

Nếu bạn chắc chắn rằng java.home được thiết lập một cách chính xác trong tất cả các ứng dụng java của bạn sau đó có thể sử dụng như mô tả trong câu trả lời khác

Trợ giúp để có được con đường một quá trình id của How do I get the path of a process in Unix/Linux

tương tự cần cho các cửa sổ.chắc chắn nó có như đã nhìn thấy nó trong các công cụ

0

Nếu bạn muốn biên dịch chương trình trong chương trình của bạn lý do tại sao bạn không chỉ cần có những phương pháp sau đây:

JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); 
    compiler.run(/* your arguments here */); 

Mô tả đầy đủ here.

2

Tôi không biết thỏa thuận lớn là gì.

public class Main implements Serializable{ 
    public static void main(String[] args) { 
     System.out.println(System.getenv("JAVA_HOME")); 
    } 
} 

In C:\Program Files\Java\jdk1.7.0 trên cửa sổ và /usr/java/jdk1.7.0_13 trên hệ thống Unix. Nếu thuộc tính môi trường JAVA_HOME không được đặt, thì null sẽ được trả về. Bạn nên thực hiện điều đó để có nghĩa là java chưa được cài đặt/cấu hình đúng cách và do đó ứng dụng của bạn không thể hoạt động.

0

Đặt cược tốt nhất của bạn có lẽ là xem xét giá trị System.getProperty("sun.boot.class.path"), mã hóa nó trên giá trị System.getProperty("path.separator") và tìm các tệp JAR JDK chuẩn.

Ví dụ, trên hệ thống của tôi, tôi nhận được (cắt ngắn để có thể đọc):

sun.boot.class.path = "/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Classes/jsse.jar:/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Classes/laf.jar: "

path.separator = ":"

này dễ dàng cho phép tôi làm việc ra rằng tất cả các file hệ thống JAR nằm trong số /System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Classes/.

Thật không may, điều này không hữu ích lắm bởi vì Tôi đang chạy OS X, có cấu trúc cài đặt Java không chuẩn. Nếu bạn không nhắm mục tiêu các máy OS X, bạn có thể tìm ra thư mục cài đặt thông qua giá trị mà chúng tôi vừa tính toán (tôi tin rằng đó là thư mục mẹ của giá trị).

Nếu bạn cũng muốn hỗ trợ OS X, bạn có thể phải sử dụng thuộc tính hệ thống os.name và viết mã bổ trợ.

0

Chỉ cần tò mò ... nếu u muốn biên dịch mã java khác khi chạy, tại sao không sử dụng API trình biên dịch Java? Trừ khi bạn đang gọi trình biên dịch java bằng cách sử dụng hàm exec Runtime()

1

Biến JAVA_HOME trong System.getProperties() đề cập đến JRE chứ không phải JDK. Bạn sẽ có thể tìm thấy JDK với:

Map<String, String> env = System.getenv(); 
for (String envName : env.keySet()) 
{ 
System.out.format("%s=%s%n", 
envName, 
env.get(envName)); 
}