从java代码中以编程方式查找java.exe绝对路径

sczxawaw  于 2023-06-20  发布在  Java
关注(0)|答案(6)|浏览(149)

如果我有一个用户启动的java jar或类文件(假设java路径在环境变量中设置),那么我如何从代码中找出启动该文件的java.exe/javaw.exe的绝对路径。
在Ubuntu上,我们可以运行:% which java,显示路径。
然而在Windows上,如果我检查System.getenv(),可能会发现有多个路径,例如旧版本或新版本。如果通过cmd行,我运行java -version,它不显示路径。
你能告诉我,无论是通过纯java或命令行在windows上是如何可能找到的位置javaw.exe?

ffvjumwh

ffvjumwh1#

String javaHome = System.getProperty("java.home");

你能告诉我通过纯Java ...在windows上如何找出javaw.exe的位置?

例如

import java.io.File;

class JavawLocation {

    public static void main(String[] args) {
        String javaHome = System.getProperty("java.home");
        File f = new File(javaHome);
        f = new File(f, "bin");
        f = new File(f, "javaw.exe");
        System.out.println(f + "    exists: " + f.exists());
    }
}

输出

C:\Program Files (x86)\Java\jdk1.6.0_29\jre\bin\javaw.exe    exists: true
Press any key to continue . . .

是的,我相信这将在JRE中工作。

sqserrrh

sqserrrh2#

在Windows上,java.library.path系统属性以bin目录的路径开头,该目录包含用于运行jar文件的java.exe。
这是有道理的,因为在Windows上,任何可执行文件查找DLL文件的第一个地方是包含可执行文件本身的目录。因此,当JVM运行时,它查找DLL的第一个地方自然是包含java.exe的目录。
您可以获取java.exe的路径,如下所示:

final String javaLibraryPath = System.getProperty("java.library.path");
final File javaExeFile = new File(
  javaLibraryPath.substring(0, javaLibraryPath.indexOf(';')) + "\\java.exe"
);
final String javaExePath =
  javaExeFile.exists() ? javaExeFile.getAbsolutePath() : "java";

此代码是Windows特定的-我硬编码了路径分隔符(;)和文件分隔符()。我还放了一个后备选项,就是“java”,以防库路径技巧不起作用。
我已经在Windows 7上用Java 6和7测试过了。我尝试了32位和64位版本的Java。

xfyts7mz

xfyts7mz3#

这是我想到的一个稍微通用的解决方案。可能有用:

private static String javaExe()
{
    final String JAVA_HOME = System.getProperty("java.home");
    final File BIN = new File(JAVA_HOME, "bin");
    File exe = new File(BIN, "java");

    if (!exe.exists())
    {
        // We might be on Windows, which needs an exe extension
        exe = new File(BIN, "java.exe");
    }

    if (exe.exists())
    {
        return exe.getAbsolutePath();
    }

    try
    {
        // Just try invoking java from the system path; this of course
        // assumes "java[.exe]" is /actually/ Java
        final String NAKED_JAVA = "java";
        new ProcessBuilder(NAKED_JAVA).start();

        return NAKED_JAVA;
    }
    catch (IOException e)
    {
        return null;
    }
}
cqoc49vn

cqoc49vn4#

上述所有方法的汇编

static String getJavaPath(){

        String tmp1 = System.getProperty("java.home") + "\\bin\\java.exe";
        String tmp2 = System.getProperty("sun.boot.library.path") + "\\java.exe";
        String tmp3 = System.getProperty("java.library.path")+ "\\java.exe";
        if(new File(tmp1).exists()) {
            return tmp1;
        }else if(new File(tmp2).exists()){
            return tmp2;
        }else if(new File(tmp3).exists()) {
            return tmp3;
        }else{
            String[] paths = System.getenv("PATH").split(";");
            for(String path:paths){
                if(new File(path + "\\java.exe").exists()){
                    return path + "\\java.exe";
                }
            }
        }
        return "";
    }
6qfn3psc

6qfn3psc5#

使用"System.getProperty("java.home");"的一个问题是,jar并不总是在java exe上运行,如果你想得到它,你可以使用"System.getProperty("sun.boot.library.path");",从那里你可以找到“java”,“java.exe”,“javaw”或“javaw.exe”...然而,这仍然有一个问题,如果可执行文件被重命名,java将运行得很好,并且实际的java可执行文件的结构从不同的JRE/JDKS更改,所以如果它被重命名,没有太多的方法可以找到java exe。除非其他人有一个ofc的方法,在这种情况下,你能分享吗?:)
(Also,我看到有人建议使用System.getProperty("java.library.path");的第一个索引,注意,如果用户/启动器手动设置了库路径,这可能不起作用,这并不罕见)

jdzmm42g

jdzmm42g6#

如果你运行的是Java 9+,你可以使用下面的代码片段来检查Java命令:

import java.io.IOException;
import java.util.Optional;

public class ProcessUtils {
  private ProcessUtils() {}

  public static Optional getCommandOfCurrentProcess() {
     ProcessHandle processHandle = ProcessHandle.current();
     return processHandle.info().command();
  }

  public static void main(String[] args) throws IOException {
    System.out.println(ProcessUtils.getCommandOfCurrentProcess());
  }
}

这将使用新的Java Process API来获取自身的句柄。从那里您可以根据需要解析路径。
Source

相关问题