如何更改从/ usr / libexec / java_home返回的Mac OS默认Java VM

时间:2013-07-26 15:36:19

标签: java macos java-home

(不确定这是否应该继续使用SU ...迁移肯定是一种选择,但是更多的程序员在这里阅读问题,所以这里有了。)

我正在运行Mac OS X 10.8.4,我安装了Apple的JDK 1.6.0_51以及Oracle的JDK 1.7.0_25。我最近为一些需要它的预发布软件安装了Oracle的1.8预览JDK。现在,当我运行/ usr / libexec / java_home时,我得到了这个:

$ /usr/libexec/java_home -V
Matching Java Virtual Machines (4):
    1.8.0, x86_64:  "Java SE 8" /Library/Java/JavaVirtualMachines/jdk1.8.0.jdk/Contents/Home
    1.7.0_25, x86_64:   "Java SE 7" /Library/Java/JavaVirtualMachines/jdk1.7.0_25.jdk/Contents/Home
    1.6.0_51-b11-457, x86_64:   "Java SE 6" /System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home
    1.6.0_51-b11-457, i386: "Java SE 6" /System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home

然而,运行:

$ java -version

返回:

java version "1.8.0-ea"

这意味着Java的默认版本目前是预发布版本,它打破了一些“普通”软件包(在我的例子中是VisualVM)。

我无法设置JAVA_HOME因为启动应用程序会忽略环境变量,即使从命令行启动(例如$ open /Applications/VisualVM.app)。

那么,我可以编辑一个文件,在那里我可以设置我的JVM订购首选项全球吗?

(请不要告诉我启动Java首选项面板,因为它根本不起作用:它不包含任何有用的东西,只列出我安装的4个JVM中的一个。)

更新

Oracle JVM位于/Library/Java/JavaVirtualMachines。将JDK 1.8目录重命名为jdk1.8.0.jvm.xyz不会改变任何内容:java_home仍然可以在正确的位置找到它,并且运行/ usr / bin / java仍然执行1.8 JVM。对于synlinks等,这不是问题。

类似问题的答案

虽然this answer提供的东西相当于一个黑客,它将删除java_home中的Java版本,但它仍然没有回答如何 java_home选择其默认值以及是否用户是否可以non-destructively set it

12 个答案:

答案 0 :(得分:85)

我认为JAVA_HOME是你能做的最好的事情。像javajavac这样的命令行工具会尊重该环境变量,您可以使用/usr/libexec/java_home -v '1.7*'JAVA_HOME提供合适的值以进行命令行工具使用Java 7。

export JAVA_HOME="`/usr/libexec/java_home -v '1.7*'`"

但标准的双击应用程序包不会使用/Library/Java下安装的JDK。使用Apple .app的旧式JavaApplicationStub捆绑包将使用来自/System/Library/Frameworks的Apple Java 6,而使用AppBundler而不使用捆绑式JRE构建的新式捆绑包将使用“公共” /Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home中的JRE - 它在存根代码中是硬编码的,无法更改,并且您不能同时安装两个不同的公共JRE。


编辑:我已经专门看了一下VisualVM,假设您正在使用the download page中的“应用程序包”版本,而这个特定的应用程序不是AppBundler应用程序,而是它的主要可执行文件是一个shell调用许多其他shell脚本并读取各种配置文件的脚本。它默认从/Library/Java中选择最新的JDK,只要它是7u10或更高版本,或者如果Java 7安装是更新9或更早版本,则使用Java 6。但是解开shell脚本中的逻辑,它在我看来就像你可以使用配置文件指定一个特定的JDK。

创建一个文本文件~/Library/Application Support/VisualVM/1.3.6/etc/visualvm.conf(用您正在使用的任何版本的VisualVM替换1.3.6)包含该行

visualvm_jdkhome="`/usr/libexec/java_home -v '1.7*'`"

这将迫使它选择Java 7而不是8。

答案 1 :(得分:48)

我也一直在那里搜索/usr/libexec/java_home如何工作,但我找不到任何关于它如何确定它列出的可用Java虚拟机的信息。

我进行了一些实验,我认为它只是执行一个ls /Library/Java/JavaVirtualMachines,然后检查它在那里找到的所有运行时的./<version>/Contents/Info.plist

然后它按Info.plist中包含的键JVMVersion对它们进行降序排序,默认情况下,它使用第一个条目作为其默认JVM。

我认为我们唯一可能做的就是更改plist:sudo vi /Library/Java/JavaVirtualMachines/jdk1.8.0.jdk/Contents/Info.plist,然后将JVMVersion从1.8.0修改为其他使其将其排序到底部而不是顶部的东西,如!1.8.0

类似的东西:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    ...
    <dict>
            ...
            <key>JVMVersion</key>
            <string>!1.8.0</string>   <!-- changed from '1.8.0' to '!1.8.0' -->`

然后它神奇地从列表顶部消失:

/usr/libexec/java_home -verbose
Matching Java Virtual Machines (3):
    1.7.0_45, x86_64:   "Java SE 7" /Library/Java/JavaVirtualMachines/jdk1.7.0_45.jdk/Contents/Home
    1.7.0_09, x86_64:   "Java SE 7" /Library/Java/JavaVirtualMachines/jdk1.7.0_09.jdk/Contents/Home
    !1.8.0, x86_64: "Java SE 8" /Library/Java/JavaVirtualMachines/jdk1.8.0.jdk/Contents/Home

现在您需要退出/登录,然后:

java -version
java version "1.7.0_45"

: - )

当然我不知道现在是否还有其他问题,或者1.8.0-ea版本的java是否仍能正常运行。

您可能不应该执行任何此操作,而只需卸载1.8.0。

然而到目前为止,这对我有用。

答案 2 :(得分:5)

Oracle的uninstallation instructions for Java 7为我工作。

摘录:

  

卸载JDK   要卸载JDK,您必须具有管理员权限并以root身份或使用sudo(8)工具执行remove命令。

     

导航到/ Library / Java / JavaVirtualMachines并删除名称与以下格式匹配的目录:*

     

/Library/Java/JavaVirtualMachines/jdk<major>.<minor>.<macro[_update]>.jdk

     

例如,卸载7u6:

     

% rm -rf jdk1.7.0_06.jdk

答案 3 :(得分:5)

实际上很容易。 假设我们在JavaVirtualMachines文件夹中有这个:

  • jdk1.7.0_51.jdk
  • jdk1.8.0.jdk

想象一下1.8是我们的默认值,然后我们只添加一个新文件夹(例如'old')并将默认的jdk文件夹移动到该新文件夹。 做java -version再次等瞧,1.7!

答案 4 :(得分:5)

非常简单,如果你不介意卷起袖子...... / Library / Java / Home 是JAVA_HOME的默认设置,它是&#39;只是一个指向其中一个的链接:

  • /系统/图书馆/的Java / JavaVirtualMachines / 1。?。?。JDK /内容/首页
  • /库/的Java / JavaVirtualMachines / jdk1。?。?_ ??。JDK /内容/首页

所以我想更改我的默认JVM / JDK版本而不用更改JAVA_HOME的内容... / Library / Java / Home是当前JVM / JDK的标准位置,而且#39我希望保留的东西......在我看来,最简单的方法就是用最少的副作用改变事物。

实际上非常简单。为了改变你用java -version看到的java版本,你所要做的就是它的一些版本:

cd /Library/Java
sudo rm Home
sudo ln -s /Library/Java/JavaVirtualMachines/jdk1.8.0_60.jdk/Contents/Home ./Home

我还没有花时间,但是一个非常简单的shell脚本使用/ usr / libexec / java_home和ln重新指定上面的符号链接应该很容易创建傻...

一旦你改变了/ Library / Java / Home指向的位置......你得到了正确的结果:

cerebro:~ magneto$ java -version
java version "1.8.0_60"
Java(TM) SE Runtime Environment (build 1.8.0_60-b27) Java HotSpot(TM)
64-Bit Server VM (build 25.60-b23, mixed mode)

答案 5 :(得分:4)

有点晚,但因为这是Mac OSX的持续问题...

我发现最简单的解决方案是简单地删除Apple安装的OpenJDK内容。每次Mac OSX更新到达时,都会安装,您需要再次删除它。

如果您使用Java在Mac上为Google App Engine开发应用程序,这非常有效。 OpenJDK运行不正常,Mac OSX Yosemite升级附带的Java版本将使App Engine的Eclipse插件在每次部署时崩溃,并显示有用的错误:“读取超时”。

答案 6 :(得分:1)

我测试了“ jenv”和其他类似设置“ JAVA_HOME”的方法,但均未成功。 现在,我并提出以下解决方案

function setJava {
    export JAVA_HOME="$(/usr/libexec/java_home -v $1)"
    launchctl setenv JAVA_HOME $JAVA_HOME
    sudo ln -nsf "$(dirname ${JAVA_HOME})/MacOS" /Library/Java/MacOS 
    java -version
}

(添加到〜/ .bashrc或〜/ .bash.profile或〜/ .zshrc中)

然后这样叫:

setJava 1.8

java_home将处理错误的输入。所以你不能做错什么。 Maven和其他东西现在将选择正确的版本。

答案 7 :(得分:1)

我实际上在反汇编程序中对此有所了解,因为源不可用。

/ usr / bin / java和/ usr / libexec / java_home都使用JavaLaunching.framework。实际上,确实先由/ usr / bin / java和朋友(而不是/ usr / libexec / java_home)检查JAVA_HOME环境变量。该框架使用JAVA_VERSION和JAVA_ARCH环境变量来过滤可用的JVM。因此,默认情况下:

$ /usr/libexec/java_home -V
Matching Java Virtual Machines (2):
    11.0.5, x86_64: "Amazon Corretto 11"    /Library/Java/JavaVirtualMachines/amazon-corretto-11.jdk/Contents/Home
    1.8.0_232, x86_64:  "Amazon Corretto 8" /Library/Java/JavaVirtualMachines/amazon-corretto-8.jdk/Contents/Home

/Library/Java/JavaVirtualMachines/amazon-corretto-11.jdk/Contents/Home

但是设置,例如JAVA_VERSION可以覆盖默认值:

$ JAVA_VERSION=1.8 /usr/libexec/java_home
/Library/Java/JavaVirtualMachines/amazon-corretto-8.jdk/Contents/Home

您还可以设置JAVA_LAUNCHER_VERBOSE = 1来同时使用/ usr / bin / java和/ usr / libexec / java_home查看一些其他调试日志,包括搜索路径,找到的JVM等。

过去,JavaLaunching.framework实际上使用首选项系统(在com.apple.java.JavaPreferences域下)来设置首选的JVM顺序allowing the default JVM to be set with PlistBuddy-但据我所知,该代码在最新版本的macOS中已被删除。环境变量似乎是唯一的方法(除了编辑JDK捆绑包本身中的Info.plist。)

如果需要在会话级别进行设置,当然可以通过.profile或通过launchd来设置默认环境变量。

答案 8 :(得分:-1)

MacOS使用/ usr / libexec / java_home查找当前的Java版本。绕过的一种方法是更改​​plist文件,如上面的@ void256所述。 其他方法是备份java_home并将其替换为您自己的脚本java_home,其代码为         echo $ JAVA_HOME

现在,通过将以下命令添加到〜/ .bash_profile,将JAVA_HOME导出到所需的SDK版本。         export JAVA_HOME =&#34; /System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home"         launchctl setenv JAVA_HOME $ JAVA_HOME ///使环境变量全局

运行命令source~ / .bash_profile以运行上述命令。

任何时候需要更改JAVA_HOME,他都可以重置〜/ .bash_profile文件中的JAVA_HOME值。

答案 9 :(得分:-2)

编辑:此信息专门针对visualvm,不适用于任何其他Java应用

正如其他人所说,你需要修改visualvm.conf

对于Mac上的最新版本的JvisualVM 1.3.6,安装目录已更改。

目前正在进行中 的 /Applications/VisualVM.app/Contents/Resources/visualvm/etc/visualvm.conf 即可。

但是,这可能取决于您安装VisualVM的位置。查找VisualVM启动位置的最简单方法,然后使用以下方法查看该过程:

ps -ef | grep VisualVM

你会看到类似的东西:

... -Dnetbeans.dirs = / Applications / VisualVM.app / Contents / Resources / visualvm / visualvm ...

您想获取netbeans.dir属性并查找目录,您将找到etc文件夹。

取消注释visualvm.conf中的这一行并将路径更改为jdk

visualvm_jdkhome="/path/to/jdk"

此外,如果您的visualvm速度很慢并且内存很多,我建议大大增加可用内存量并在服务器模式下运行它:

visualvm_default_options="-J-XX:MaxPermSize=96m -J-Xmx2048m -J-Xms2048m -J-server -J-XX:+UseCompressedOops -J-XX:+UseConcMarkSweepGC -J-XX:+UseParNewGC -J-XX:NewRatio=2 -J-Dnetbeans.accept_license_class=com.sun.tools.visualvm.modules.startup.AcceptLicense -J-Dsun.jvmstat.perdata.syncWaitMs=10000 -J-Dsun.java2d.noddraw=true -J-Dsun.java2d.d3d=false"

答案 10 :(得分:-2)

我有类似的情况,以下过程对我有用:

  1. 在终端中输入

    vi ~/.profile
    
  2. 然后在文件中添加此行,并保存

    export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk<version>.jdk/Contents/Home
    

    其中version是您计算机上的版本,例如1.7.0_25

  3. 退出编辑器,然后输入以下命令使其生效

    source ~/.profile 
    
  4. 然后键入java -version以检查结果

        java -version 
    

    什么是.profile? 从:http://computers.tutsplus.com/tutorials/speed-up-your-terminal-workflow-with-command-aliases-and-profile--mac-30515

      

    .profile文件是一个隐藏文件。它是一个可选文件,告诉系统当用户的配置文件登录时要运行哪些命令。例如,如果我的用户名是bruno,并且/ Users / bruno /中有.profile文件,则其所有内容将在登录过程中执行。

答案 11 :(得分:-3)

我想将默认的java版本1.6 *更改为1.7 *。我尝试了以下步骤,它对我有用:

  • 从/ usr / bin
  • 下删除了链接“java”
  • 再次创建它,指向新位置:

ln -s /Library/Java/JavaVirtualMachines/jdk1.7.0_51.jdk/Contents/Home/bin/java java

  • 使用“java -version”验证

java版“1.7.0_51”
Java(TM)SE运行时环境(版本1.7.0_51-b13)
Java HotSpot(TM)64位服务器VM(内置24.51-b03,混合模式)