How can I change Mac OS's default Java VM returned from /usr/libexec/java_home
java, java-home, macos
Solution
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.
Problem
(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.