Java – How to change Mac OS’s default Java VM returned from /usr/libexec/java_home

javajava-homemacos

(Wasn't sure if this should go on SU… migration is certainly an option, but more programmers read questions here, so here goes).

I am running Mac OS X 10.8.4, and I have Apple's JDK 1.6.0_51 installed as well as Oracle's JDK 1.7.0_25. I recently installed Oracle's 1.8 preview JDK for some pre-release software that requires it. Now, when I run /usr/libexec/java_home, I get this:

$ /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

Great.

However, running:

$ java -version

Returns:

java version "1.8.0-ea"

That means that the default version of Java is currently the pre-release version, which breaks some "normal" packages (in my case, VisualVM).

I can't set JAVA_HOME because launching applications ignores environment variables, even when launching from the command line (e.g. $ open /Applications/VisualVM.app).

So, is there a file I can edit where I can set my JVM ordering preferences globally?

(Please don't tell me to launch the Java Preferences Panel because that simply does not work: it does not contain anything useful and only lists one of the 4 JVMs that I have installed.)

Update:

Oracle JVMs live in /Library/Java/JavaVirtualMachines. Re-naming the JDK 1.8 directory to jdk1.8.0.jvm.xyz does not change anything: java_home still finds it in the right place, and running /usr/bin/java still executes the 1.8 JVM. This is not an issue with synlinks, etc.

Answers to Similar Questions

While this answer offers what amounts to a hack that will remove versions of Java from being picked up by java_home, it still does not answer this question of how java_home chooses its default and whether or not users can non-destructively set it.

Best Answer

I think JAVA_HOME is the best you can do. The command-line tools like java and javac will respect that environment variable, you can use /usr/libexec/java_home -v '1.7*' to give you a suitable value to put into JAVA_HOME in order to make command line tools use Java 7.

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

But standard double-clickable application bundles don't use JDKs installed under /Library/Java at all. Old-style .app bundles using Apple's JavaApplicationStub will use Apple Java 6 from /System/Library/Frameworks, and new-style ones built with AppBundler without a bundled JRE will use the "public" JRE in /Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home - that's hard-coded in the stub code and can't be changed, and you can't have two different public JREs installed at the same time.


Edit: I've had a look at VisualVM specifically, assuming you're using the "application bundle" version from the download page, and this particular app is not an AppBundler application, instead its main executable is a shell script that calls a number of other shell scripts and reads various configuration files. It defaults to picking the newest JDK from /Library/Java as long as that is 7u10 or later, or uses Java 6 if your Java 7 installation is update 9 or earlier. But unravelling the logic in the shell scripts it looks to me like you can specify a particular JDK using a configuration file.

Create a text file ~/Library/Application Support/VisualVM/1.3.6/etc/visualvm.conf (replace 1.3.6 with whatever version of VisualVM you're using) containing the line

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

and this will force it to choose Java 7 instead of 8.