C:\ProgramData\Oracle\Java\javapath\java.exe 使用哪个 JRE?

34
我正试图找出Java用于查找/检测由C:\ProgramData\Oracle\Java\javapath\java.exe使用的JRE的环境变量。
根据Oracle的设计,我在C:\ProgramData\Oracle\Java\javapath\中只有以下文件:
- java.exe - javaw.exe - javaws.exe 如果我将JAVA_HOME设置为空或设置为某个随机文件夹,则仍可以使用java.exe运行应用程序。因此,我只能假设它不使用JAVA_HOME值。那么它如何找到JRE文件夹呢?它是否默认使用特定的值?我也没有设置JRE_HOME变量。

你看了你的PATH环境变量吗? - OldProgrammer
1
@OldProgrammer 当然可以。我在那里定义了其他的Java路径。但是,java.exe会使用路径环境变量来查找它所需的必要库吗?我本来以为它需要JAVA_HOME变量,而不是期望使用PATH变量。通常,我希望使用PATH来查找可执行文件。此外,如果我清除PATH变量,只定义C:\ProgramData\Oracle\Java\javapath\,Java仍然可以运行。 - Eric B.
我相信除了路径变量之外,system32中的java.exe还使用了regedit查找。这种行为浪费了我很多时间... - 98percentmonkey
@EricB. 为了在Windows或Linux中运行任何程序,要么文件在当前目录中,要么您提供可执行文件的完整路径,要么该目录包含在PATH环境变量中。 - Clon
5个回答

40

截至2018年,特别是关于Oracle Java,您可能会发现您的Java运行时安装在以下两种方式之一中:

带有文件符号链接的常规目录

如果您查看C:\ProgramData\Oracle\Java\javapath\中的文件,则会发现它们实际上是指向特定java二进制文件的符号链接。

2015-11-13  06:11 PM    <SYMLINK>      java.exe [C:\Program Files\Java\jre1.8.0_65\bin\java.exe]
2015-11-13  06:11 PM    <SYMLINK>      javaw.exe [C:\Program Files\Java\jre1.8.0_65\bin\javaw.exe]
2015-11-13  06:11 PM    <SYMLINK>      javaws.exe [C:\Program Files\Java\jre1.8.0_65\bin\javaws.exe]

目录联接器中包含常规文件

使用最新的(64位)Java 8安装实际上将系统路径添加到另一个位置:c:\Program Files (x86)\Common Files\Oracle\Java\javapath。 这次,javapath本身是联接器:

2018-07-21  05:59 PM    <JUNCTION>     javapath [C:\Program Files (x86)\Common Files\Oracle\Java\javapath_target_172906453]
2018-07-21  05:59 PM    <DIR>          javapath_target_172906453

有趣的是,现在 javapath_target_... 文件夹中的 java.exe 等文件不是符号链接。这些文件使用此注册表位置查找 JRE 和 JDK 版本:

[HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Runtime Environment]
"CurrentVersion"="1.8"

[HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Runtime Environment\1.8]
"JavaHome"="C:\\Program Files\\Java\\jre1.8.0_65"

2
有趣的是,我尝试通过注册表更改版本,然后出现“错误:注册表键'Software\JavaSoft\Java Runtime Environment'\CurrentVersion'的值为'11.0.5',但需要'1.8'。” - OrangeDog

23

这会给你一个想法:

java -verbose | more

2
谢谢。它指向了c:\Program Files(x86)\java文件夹。我仍然不确定为什么它默认到那里,但至少我现在知道它在哪里查找了。 - Eric B.

16

这些“新”的JDK 8/64位行为非常难懂,我无法猜测为什么我的应用程序不会启动,因为我已经安装了JDK(带有私有JRE)并设置了每个路径变量,但仍然无法启动。过了一段时间,我单独安装了JRE8,它就可以工作了。首先,注册表键值仅由公共JRE编写......好的。

然后我想知道应用程序使用哪个运行时,我重命名了所有java*.exe,但它仍然以64位工作,我重命名了所有新的注册表键,它仍然能工作......

故事结束:在Windows 64中,注册表键位于HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft(32位)和HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\JavaSoft(64位),我的应用程序之所以能工作是因为...

HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\JavaSoft\Java Runtime Environment\1.8\RuntimeLib\ 

指向 jvm.dll 的是一个符号链接。我需要一杯啤酒,我想要另一份工作 :-)

这里有一个很好的链接,解释了 Regedit-Keys 以及 Java 使用的不同 "发现方法" 来查找最新安装的版本:

http://mindprod.com/jgloss/registry.html

但是,在 JRE8u171 之前引入的 SYSLink - Change 似乎是一项未记录的更改。

我的 SYSLink 路径是 C:\Program Files (x86)\Common Files\Oracle\Java,实际上是一个子目录的联接。而 JDK8 安装程序会将 java*.exe 文件复制到 Windows\System32\ 中。

更多信息:

对不起,我发了一通牢骚,我现在很沮丧。希望它能帮助其他人。


3
"WOW6432Node"实际上是32位应用程序使用的注册表节点。 - Gerrit

7

尝试使用findstr和-java选项

示例:

C:\>java -verbose 2>nul | findstr /I opened
[Opened C:\Program Files\Java\jre1.8.0_201\lib\rt.jar]

(或者只尝试使用java -verbose--这将输出很多文本。并且您的Java标准JARs的路径将被多次包含。)

尝试使用/s查询注册表

示例:

C:\>reg query "HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Runtime Environment" /s

HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Runtime Environment
    CurrentVersion      REG_SZ    1.8
    BrowserJavaVersion  REG_SZ    11.201.2

HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Runtime Environment\1.8
    RuntimeLib      REG_SZ    C:\Program Files\Java\jre1.8.0_201\bin\server\jvm.dll
    JavaHome        REG_SZ    C:\Program Files\Java\jre1.8.0_201
    MicroVersion    REG_SZ    0

HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Runtime Environment\1.8.0_201
    JavaHome        REG_SZ    C:\Program Files\Java\jre1.8.0_201
    MicroVersion    REG_SZ    0
    RuntimeLib      REG_SZ    C:\Program Files\Java\jre1.8.0_201\bin\server\jvm.dll

HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Runtime Environment\1.8.0_201\MSI
    INSTALLDIR      REG_SZ    C:\Program Files\Java\jre1.8.0_201\
    JU              REG_SZ
    OEMUPDATE       REG_SZ
    FROMVERSION     REG_SZ    NA
    FROMVERSIONFULL REG_SZ
    PRODUCTVERSION  REG_SZ    8.0.2010.9
    EULA            REG_SZ
    JAVAUPDATE      REG_SZ    1
    AUTOUPDATECHECK REG_SZ    1
    AUTOUPDATEDELAY REG_SZ
    FullVersion     REG_SZ    1.8.0_201-b09


C:\>

尝试运行 Get-Command java

注意:如果你只关心版本号,那么你可以尝试使用 PowerShell 的 Get-Command 命令:

PS C:\> Get-Command java | ft -AutoSize

CommandType  Name      Version    Source
-----------  ----      -------    ------
Application  java.exe  8.0.201.9  C:\Program Files (x86)\Common
Files\Oracle\Java\javapath\java.exe

0

最近我遇到了这个问题,因为我添加了JAVA 9、11和17以及之前的JAVA 6和8版本。我错误地认为环境变量在新版本中没有改变,但显然我错了。

当我运行java -version时,它返回JAVA 9,而javac -version返回JAVA 17。
我错误地尝试添加一个%JAVA_HOME%变量,就像在Windows环境设置中的JAVA 8版本之前一直做的那样。然而,尽管将该添加移动到PATH的前面,它并没有改变任何东西!

正如已经解释的那样,这个Windows文件夹:C:\ProgramData\Oracle\Java\javapath是java设置了3个符号链接的地方,这些符号链接将覆盖您所做的PATH更改,并且确实指向我从java和javac的-version返回的JAVA版本。

我在这里找到了两个解决方案:JDK 8 and C:\ProgramData\Oracle\Java\javapath

如何在cmd中更灵活地切换JDK版本。您可以将自己的目录前置到PATH中以覆盖Oracle,也可以按照惯例将其附加到PATH变量的末尾,就像一直以来做的那样。我更喜欢第二种方法,以下是如何操作。

第二种解决方案使用了两个批处理文件,其中一个环境变量JAVA_HOME设置与我一直使用的类似。

我发布这篇文章是为了提供一种解决方案,以防有人需要解决方法。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接