我想在多个操作系统上找到JDK路径。
我不确定这是否有一种很好的方法,因为我一直在尝试和失败。
对于Windows,它会是这样的 - C:\Program Files\Java\jdk1.7.0_07
或者这个
C:\Program Files(x86)\Java\jdk1.7.0_07
对于Linux,它将是这样的 - /usr/java/jdk1.7.0_07
我希望这适用于安装的任何JDK版本,因此Java \ jdk之后的数字无关紧要。
我将使用System.setProperty("java.home", path);
基本上,我要做的是当我运行我的程序时,将java.home设置为当前机器上安装的JDK,但获得JDK路径证明是非常困难的,任何解决方案?
答案 0 :(得分:7)
您可以通过查看javac的安装位置来查找JDK路径。 假设“javac”在系统的环境路径中,那么您可以通过将“where javac”传递给代码来检索路径,例如以下
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;
}
返回的字符串将是javac的确切位置,因此您可能需要额外的处理来获取javac所在的目录。您需要区分Windows和其他操作系统
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
注意:如果方法返回null / error并不意味着javac不存在 - 很可能是javac不在Windows上的PATH环境变量中,因此无法使用此方法找到。这在Unix上不太可能,因为Unix通常会自动将jdk / bin目录添加到PATH。 此外,这将返回当前在命令行中使用的javac版本,不一定是安装的最新版本。如果是安装了7u12和7u13但是命令提示符设置为使用7u12,那就是将返回的路径。
仅在多台Windows计算机上进行了测试,但在这些计算机上运行良好。
希望这有帮助。
答案 1 :(得分:2)
JAVA_HOME应该指向所有操作系统中的JDK安装路径和JRE_HOME到JRE安装路径
答案 2 :(得分:2)
我不知道重要的是什么。
public class Main implements Serializable{
public static void main(String[] args) {
System.out.println(System.getenv("JAVA_HOME"));
}
}
在Windows上打印C:\Program Files\Java\jdk1.7.0
,在unix系统上打印/usr/java/jdk1.7.0_13
。如果未设置环境属性JAVA_HOME
,则返回null。你应该认为java没有正确安装/配置,因此你的应用程序无法运行。
答案 3 :(得分:1)
System.getProperties()中的JAVA_HOME变量引用JRE而不是JDK。您应该能够找到JDK:
Map<String, String> env = System.getenv();
for (String envName : env.keySet())
{
System.out.format("%s=%s%n",
envName,
env.get(envName));
}
答案 4 :(得分:0)
System.getProperty(“java.home”)对你不够好?
如果它以“jre”结尾,你就会知道这是jre,你可以尝试走路并找到根文件夹并检查只有JDK才能确定的不同文件。
答案 5 :(得分:0)
System.getProperties()中的JAVA_HOME变量引用JRE而不是JDK。 您应该能够找到JDK:
Map<String, String> env = System.getenv();
for (String envName : env.keySet())
{
System.out.format("%s=%s%n",
envName,
env.get(envName));
}
答案 6 :(得分:0)
以下是我对此的看法: 您可以选择要安装jdk的位置,也可以安装多个jdk。所以我不认为可以有一个标准变量。
让我们假设标准目录结构已用于安装jdk。在这种情况下,jre和jdk安装将位于同一目录下。
因此,一旦获得System.getProperty(“java.home”),则只需搜索目录即可。
希望有所帮助。
答案 7 :(得分:0)
上帝这是如此令人费解,但我完成了。虽然它只在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);
}
}
基本上做的是获取所有系统变量并查找其中一个是否包含java版本(我获取JDK路径的方式)。由于系统变量路径实际上位于JDK bin文件夹中,因此它将JDK路径String
转换为File
并将一个文件夹返回到JDK目录。
答案 8 :(得分:0)
您可以使用java的getenv函数来获取PATH。
答案 9 :(得分:0)
我认为你最好也是最可靠的选择(因为Java_home等不需要声明为了获得JVM,我可以在脚本中使用完整路径并启动Java。
获取java进程ID,使用API获取该进程的路径。
这不是一个完整的解决方案,而是指导方针。
如果您确定在所有Java应用程序中准确设置了java.home,那么可以按照其他答案中的描述使用它
帮助获取进程ID的路径How do I get the path of a process in Unix / Linux
同样需要Windows。我确信它已经在工具中看到了
答案 10 :(得分:0)
如果您想在程序中编译程序,为什么不采取以下方法:
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
compiler.run(/* your arguments here */);
完整说明here。
答案 11 :(得分:0)
最好的办法是查看System.getProperty("sun.boot.class.path")
的值,将其标记为System.getProperty("path.separator")
的值,并查找标准的JDK JAR文件。
例如,在我的系统上,我得到(为了便于阅读而被截断):
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 = ":"
这很容易让我知道所有系统JAR文件都在/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Classes/
。
不幸的是,这并不是非常有用,因为我正在运行OS X,它具有非标准的Java安装结构。如果你没有针对OS X机器,你可以通过我们刚刚计算的值来计算安装目录(我相信它是值的父目录)。
如果您还想支持OS X,则可能必须使用os.name
系统属性并编写add-hoc代码。
答案 12 :(得分:0)
好奇......如果你想在运行时编译其他java代码,为什么不使用Java Compiler API?除非您使用Runtime exec()
调用java编译器答案 13 :(得分:0)
在考虑@Nicolas Rinaudo 的回答后,我开始编写一些只检查系统属性中任何路径的东西。 我在 Windows 10 和 Linux (Debian 9) 上对此进行了测试,效果很好。
private static final Pattern JDK_REGEX = Pattern.compile("jdk[0-9].[0-9].[0-9]_(.*?)" + StringEscapeUtils.escapeJava(File.separator));
public static String findJDKPath() {
Enumeration<Object> properties = System.getProperties().elements();
List<String> possibilities = new ArrayList<>();
String separator = System.getProperty("path.separator");
while(properties.hasMoreElements()) {
Object element = properties.nextElement();
if (!(element instanceof String)) {
continue;
}
String string = (String) element;
String[] split = string.split(separator);
for(String s : split) {
if (s.contains("jdk") && s.contains(File.separator)) {
possibilities.add(s);
}
}
}
for(String s : possibilities) {
Matcher matcher = JDK_REGEX.matcher(s);
if (matcher.find()) {
String group = matcher.group();
return s.substring(0, s.indexOf(group) + group.length());
}
}
return null;
}