This is a note on my experience of installing Java on macOS 10.9.2.
macOS has its own system Java which as of macOS 10.9.2 is at version 1.6.0_65. It's more or less consistent with Java 6 (Java Language and Virtual Machine Specifications version SE 6). I'd like to keep macOS's system Java for various tasks and applications such as Mathematica which requires on Java 6. It's said that Apple no longer supports Java as a system component, so it's possile there will not be future major version update to Java 7 and higher.
The new "Java" I'd like to install is Oracle's Java. Oracle calls it "Java Platform (JDK) Platform". JDK is Java Development Kit which is the software package one needs to do Java software development. It's currently at version "Java SE 7" and is updated to "JDK SE 8" in March 2014. I'd like to install it for learning new Java features and used it in some projects.
macOS's system Java
The 'java' executable and Java Virtual Machines
The default command-line java
on macOS 10.9.2 is
version 1.6.0_65
:
$ which java
/usr/bin/java
$ java -version
java version "1.6.0_65"
Java(TM) SE Runtime Environment (build 1.6.0_65-b14-462-11M4609)
Java HotSpot(TM) 64-Bit Server VM (build 20.65-b04-462, mixed mode)
This java
along with other Java related binaries in
the same path /usr/bin/
are actually symbolic links
pointing to OS X's default installation directory for Java which in
turn is part of system libraries /System/Library/
:
$ ls -l /usr/bin/*java*
lrwxr-xr-x 1 root wheel 74 Nov 3 10:29 /usr/bin/java -> /System/Library/Frameworks/JavaVM.framework/Versions/Current/Commands/java
lrwxr-xr-x 1 root wheel 75 Nov 3 10:29 /usr/bin/javac -> /System/Library/Frameworks/JavaVM.framework/Versions/Current/Commands/javac
lrwxr-xr-x 1 root wheel 77 Nov 3 10:29 /usr/bin/javadoc -> /System/Library/Frameworks/JavaVM.framework/Versions/Current/Commands/javadoc
lrwxr-xr-x 1 root wheel 75 Nov 3 10:29 /usr/bin/javah -> /System/Library/Frameworks/JavaVM.framework/Versions/Current/Commands/javah
lrwxr-xr-x 1 root wheel 75 Nov 3 10:29 /usr/bin/javap -> /System/Library/Frameworks/JavaVM.framework/Versions/Current/Commands/javap
lrwxr-xr-x 1 root wheel 76 Nov 3 10:29 /usr/bin/javaws -> /System/Library/Frameworks/JavaVM.framework/Versions/Current/Commands/javaws
So the java
at command line is actually using
/System/Library/Frameworks/JavaVM.framework/Versions/Current/Commands/java
.
The Current
directory is actually also a symbolic
link:
$ ls -la /System/Library/Frameworks/JavaVM.framework/Versions/
total 64
drwxr-xr-x 11 root wheel 374 Nov 3 10:30 .
drwxr-xr-x 12 root wheel 408 Nov 3 10:30 ..
lrwxr-xr-x 1 root wheel 10 Nov 3 10:29 1.4 -> CurrentJDK
lrwxr-xr-x 1 root wheel 10 Nov 3 10:29 1.4.2 -> CurrentJDK
lrwxr-xr-x 1 root wheel 10 Nov 3 10:29 1.5 -> CurrentJDK
lrwxr-xr-x 1 root wheel 10 Nov 3 10:29 1.5.0 -> CurrentJDK
lrwxr-xr-x 1 root wheel 10 Nov 3 10:29 1.6 -> CurrentJDK
lrwxr-xr-x 1 root wheel 10 Nov 3 10:29 1.6.0 -> CurrentJDK
drwxr-xr-x 8 root wheel 272 Nov 3 10:30 A
lrwxr-xr-x 1 root wheel 1 Nov 3 10:29 Current -> A
lrwxr-xr-x 1 root wheel 59 Nov 3 10:29 CurrentJDK -> /System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents
So this further mean the java
at command line is
actually using
/System/Library/Frameworks/JavaVM.framework/Versions/A/Commands/java
:
$ ls -la /System/Library/Frameworks/JavaVM.framework/Versions/A/Commands/java
-rwxr-xr-x 1 root wheel 54624 Nov 3 10:29 /System/Library/Frameworks/JavaVM.framework/Versions/A/Commands/java
$ /System/Library/Frameworks/JavaVM.framework/Versions/A/Commands/java -version
java version "1.6.0_65"
Java(TM) SE Runtime Environment (build 1.6.0_65-b14-462-11M4609)
Java HotSpot(TM) 64-Bit Server VM (build 20.65-b04-462, mixed mode)
Difference between /System/Library/Frameworks/
and
/Library/
:
The /System/Library/Frameworks/
path is where macOS
installs its essential framework packages such as Java. The
framework packages are shared by multiple applications. Different
applications may need different versions of the same package so in
general there can be multiple versions of the same package.
Third-party libraries is installed in /Library/
.
/System/Library/Java/
:
All the previous versions of Java {1.4
,
1.5
, ..., 1.6.0
} is redirected to
CurrentJDK
and then to
/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents
,
perhaps for backwards compatibility. And the "current" Java is
pointed to Current/
and then to A/
. I
guess 'A' stands for "Automatic". Also, I noted that there is one
Apple's Java VM:
$ ls -la /System/Library/Java/JavaVirtualMachines/
total 0
drwxr-xr-x 3 root wheel 102 Oct 10 11:13 .
drwxr-xr-x 5 root wheel 170 Nov 3 10:30 ..
drwxr-xr-x 3 root wheel 102 Oct 10 11:13 1.6.0.jdk
I'm not sure what's the relation between
/System/Library/Frameworks/JavaVM.framework/
and
/System/Library/Java
. My guess is that
JavaVM.framework
is newly introduced and used 1) as an
"interface" which maintain various links to
/System/Library/Java/
for previous versions; 2) to
store the "current" version of system "Java" in
/System/Library/Frameworks/JavaVM.framework/Versions/A/
.
Apple has a web site that provides downloading of macOS system Java.
JAVA_HOME
environment variable
$ echo $JAVA_HOME
/System/Library/Frameworks/JavaVM.framework/Home
$ ls -la /System/Library/Frameworks/JavaVM.framework/Home
lrwxr-xr-x 1 root wheel 24 Apr 1 19:36 /System/Library/Frameworks/JavaVM.framework/Home -> Versions/CurrentJDK/Home
$ ls -la /System/Library/Frameworks/JavaVM.framework/Versions/
total 64
drwxr-xr-x 11 root wheel 374 Apr 1 19:37 .
drwxr-xr-x 12 root wheel 408 Apr 1 19:37 ..
lrwxr-xr-x 1 root wheel 10 Apr 1 19:36 1.4 -> CurrentJDK
lrwxr-xr-x 1 root wheel 10 Apr 1 19:36 1.4.2 -> CurrentJDK
lrwxr-xr-x 1 root wheel 10 Apr 1 19:36 1.5 -> CurrentJDK
lrwxr-xr-x 1 root wheel 10 Apr 1 19:36 1.5.0 -> CurrentJDK
lrwxr-xr-x 1 root wheel 10 Apr 1 19:36 1.6 -> CurrentJDK
lrwxr-xr-x 1 root wheel 10 Apr 1 19:36 1.6.0 -> CurrentJDK
drwxr-xr-x 8 root wheel 272 Apr 1 19:37 A
lrwxr-xr-x 1 root wheel 1 Apr 1 19:36 Current -> A
lrwxr-xr-x 1 root wheel 59 Apr 1 19:36 CurrentJDK -> /System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents
Notice that it does not point to a Home
inside
/System/Library/Frameworks/JavaVM.framework/Versions/A/
.
Actually A/
does not contain a Home/
. I'm
not sure why there are both
/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Commands
(which points to
/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home/bin/
)
and
/System/Library/Frameworks/JavaVM.framework/Versions/A/Commands
.
(Re-)install macOS's system Java
If for some reason you need to (re-)install Apple's system Java, you can download it from Apple's support site http://support.apple.com/downloads/#java. For example, as of April 2014, I will choose "Java for OS X 2013-005" for macOS 10.9.2.
There is also packages called "Java for macOS 10.6 Update 17 Developer Package" or "Java for OS X 2013-005 Developer Package" that "contains JavaDoc, tools documentation, and native framework headers". I've never tried these.
Preventing future macOS update to Java
If you decide to use Oracle JDK exclusively in future, it maybe desirable to more "thoroughly" delete Apple's Java. This is what I've not attempted to do.
The possible removals you'd need are
$ rm -rf /System/Library/Java/JavaVirtualMachines/
$ rm /private/var/db/receipts/com.apple.pkg.JavaForMacOSX*
and edit the installation receipts
/Library/Receipts/InstallHistory.plist
and remove the
<dict>
XML elements that has
com.apple.Java*
in it:
$ ack "com\.apple.*ava.*" /Library/Receipts/InstallHistory.plist
<string>com.apple.pkg.JavaSDKLeo</string>
<string>com.apple.pkg.JavaForMacOSX10.6Update3</string>
<string>com.apple.pkg.JavaForMacOSX10.6Update4</string>
<string>com.apple.pkg.JavaForMacOSX10.6Update5</string>
<string>com.apple.pkg.JavaForMacOSX10.6</string>
<string>com.apple.pkg.JavaForMacOSX10.6</string>
<string>com.apple.pkg.JavaSecurity</string>
<string>com.apple.pkg.JavaForMacOSX10.6</string>
<string>com.apple.pkg.JavaSecurity</string>
<string>com.apple.pkg.JavaForMacOSX10.6</string>
<string>com.apple.pkg.JavaSecurity</string>
<string>com.apple.pkg.JavaForMacOSX10.6</string>
<string>com.apple.pkg.JavaSecurity</string>
<string>com.apple.pkg.JavaForMacOSX10.6</string>
<string>com.apple.pkg.JavaSecurity</string>
<string>com.apple.pkg.JavaForMacOSX10.6</string>
<string>com.apple.pkg.JavaSecurity</string>
<string>com.apple.pkg.JavaForMacOSX10.6</string>
<string>com.apple.pkg.JavaSecurity</string>
<string>com.apple.pkg.JavaTools</string>
<string>com.apple.pkg.JavaEssentials</string>
<string>com.apple.pkg.JavaEssentials</string>
<string>com.apple.pkg.JavaForMacOSX107</string>
<string>com.apple.pkg.JavaSecurity</string>
<string>com.apple.pkg.JavaMDNS</string>
<string>com.apple.pkg.JavaEssentials</string>
<string>com.apple.pkg.JavaForMacOSX107</string>
<string>com.apple.pkg.JavaSecurity</string>
<string>com.apple.pkg.JavaMDNS</string>
<string>com.apple.pkg.JavaTools</string>
<string>com.apple.pkg.JavaEssentials</string>
<string>com.apple.pkg.JavaEssentials</string>
<string>com.apple.pkg.JavaForMacOSX107</string>
<string>com.apple.pkg.JavaSecurity</string>
<string>com.apple.pkg.JavaMDNS</string>
Installing Oracle's Java
The path /Library/Java/
Third-party Java will be installed to
/Library/Java
. Note there is not a
/System/
in front of it.
$ ls -la /Library/Java
total 8
drwxrwxr-x 5 root admin 170 Nov 3 10:30 .
drwxr-xr-x+ 72 root wheel 2448 Mar 8 08:08 ..
drwxrwxr-x 2 root admin 68 Nov 3 10:30 Extensions
lrwxr-xr-x 1 root wheel 48 Nov 3 10:29 Home -> /System/Library/Frameworks/JavaVM.framework/Home
drwxr-xr-x 2 root wheel 68 Nov 3 10:30 JavaVirtualMachines
$ ls -la /Library/Java/JavaVirtualMachines/
total 0
drwxr-xr-x 2 root wheel 68 Nov 3 10:30 .
drwxrwxr-x 5 root admin 170 Nov 3 10:30 ..
The symbolic link Home ->
/System/Library/Frameworks/JavaVM.framework/Home
is how
macOS by default manages the $JAVA_HOME
environment
variable for third-party Java. $JAVA_HOME
by default
is set to /Library/Java/Home
which is updated to point
to the current version of Java
/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home/
.
Currently I have no third-party Java and hence an empty
/Library/Java/JavaVirtualMachines/
.
To install a new non-system non-Apple Java on Mac, one can install Oracle's JDK, and possibly OpenJDK). These have versions newer than Apple's Java.
My goal at the time of writing this note is to install the newer Java (Java Language and Virtual Specification, version SE 7 or even version "Java SE 8") while keep macOS's own system Java (version "Java SE 6"), since I need both for different work.
Installing Oracle's JDK
To install "Java 7", download "Java SE Development Kit 7" for
"macOS x64" from
Oracle. Install that. After that, you should find
/Library/Java/JavaVirtualMachines/
has the newly
installed Oracle JDK:
$ ls /Library/Java/JavaVirtualMachines
jdk1.7.0_51.jdk
$ /Library/Java/JavaVirtualMachines/jdk1.7.0_51.jdk/Contents/Home/bin/java -version
java version "1.7.0_51"
Java(TM) SE Runtime Environment (build 1.7.0_51-b13)
Java HotSpot(TM) 64-Bit Server VM (build 24.51-b03, mixed mode)
But this does not affect the default command-line
java
:
$ java -version
java 1.6.0_65
Now you have both Java 6 and 7 on the computer and can use them for different purposes.
Making Oracle Java binaries available at command line
Depending on if it's desirable to you, you may want to link Java
related binaries in /usr/bin
$ ls -la /usr/bin/*java*
lrwxr-xr-x 1 root wheel 74 Nov 3 10:29 /usr/bin/java -> /System/Library/Frameworks/JavaVM.framework/Versions/Current/Commands/java
lrwxr-xr-x 1 root wheel 75 Nov 3 10:29 /usr/bin/javac -> /System/Library/Frameworks/JavaVM.framework/Versions/Current/Commands/javac
lrwxr-xr-x 1 root wheel 77 Nov 3 10:29 /usr/bin/javadoc -> /System/Library/Frameworks/JavaVM.framework/Versions/Current/Commands/javadoc
lrwxr-xr-x 1 root wheel 75 Nov 3 10:29 /usr/bin/javah -> /System/Library/Frameworks/JavaVM.framework/Versions/Current/Commands/javah
lrwxr-xr-x 1 root wheel 75 Nov 3 10:29 /usr/bin/javap -> /System/Library/Frameworks/JavaVM.framework/Versions/Current/Commands/javap
lrwxr-xr-x 1 root wheel 76 Nov 3 10:29 /usr/bin/javaws -> /System/Library/Frameworks/JavaVM.framework/Versions/Current/Commands/javaws
to Oracle's Java, either under a different name, say
java7
, or the default name java
, and
optionally rename the existing macOS's java
to
java6
first. I created java7
:
$ sudo ln -s /Library/Java/JavaVirtualMachines/jdk1.7.0_51.jdk/Contents/Home/bin/java /usr/bin/java7
$ sudo ln -s /Library/Java/JavaVirtualMachines/jdk1.7.0_51.jdk/Contents/Home/bin/javac /usr/bin/javac7
...
And you probably want to keep $JAVA_HOME
consistent
with java
. If java
is pointing to Oracle
Java, you'd want
$ ln -s /Library/Java/Home /Library/Java/JavaVirtualMachines/jdk1.7.0_51.jdk/Contents/Home
Managing JAVA_HOME
for different environments
JAVA_HOME
is a UNIX envrionment variable that are
sometimes used to determine which and how Java Virtual Machine is
run. It's a somewhat complex issue to set them appropriately for
different purposes.
Here is what I've done:
Setting JAVA_HOME
for Bash
Add the following code to shell configuration file. There are
multiple configuration files for Bash shell including
.profile
, .bashrc
,
/etc/profile
. For me, I used
$HOME/.bashrc
:
## Method 1: Set JAVA_HOME to macOS's system Java Home/ which is a symlink pointing to
## /System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home as of macOS 10.9.2
## When there are multiple versions of Java installed, using the /usr/libexec/java_home method below is better.
# export JAVA_HOME="/System/Library/Frameworks/JavaVM.framework/Home"
## Method 2: Alternatively, set the path using the /usr/libexec/java_home command with a parameter -v to choose specific version of Java
## Use the following to see verbose info about available versions of Java when unsure.
## /usr/libexec/java_home -V
## /usr/libexec/java_home -Vv 1.6
## Use Java 6
export JAVA_HOME=`/usr/libexec/java_home -v 1.6`
## Use Java 7
# export JAVA_HOME=`/usr/libexec/java_home -v 1.7`
## Use Java 8
# export JAVA_HOME=`/usr/libexec/java_home -v 1.8`
So, potentially, one can tweak the lines in method 2 and choose
different version to use. Notice that the binary
/usr/libexec/java_home
is used to determine the Java
home directory:
$ /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_51, x86_64: "Java SE 7" /Library/Java/JavaVirtualMachines/jdk1.7.0_51/Contents/Home
1.6.0_65-b14-462, x86_64: "Java SE 6" /System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home
1.6.0_65-b14-462, i386: "Java SE 6" /System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home
/Library/Java/JavaVirtualMachines/jdk1.8.0.jdk/Contents/Home
It seems it recognizes all available JVMs and picks the home directory from the latest version.
Setting JAVA_HOME
for Mathematica
I'm a heavy user of Mathematica. As of Mathematica 9, it is developed based on Java 6 and its Java related functionalities such as J/Link package may not work properly if a different version of Java is used.
There are two configurations to set and/or check.
JAVA_HOME
As of Mathematica 9, verify that Mathematica's
$JAVA_HOME
is pointing to macOS's system Java's JVM
1.6.*:
In[1]:= Import["!echo $JAVA_HOME", "Text"]
Out[1]= "/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home"
In[2]:= Environment["JAVA_HOME"]
Out[2]= "/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home"
I'm not sure why the following does not work:
In[3]:= Import["!java -version", "Text"]
Out[3]= ""
CommandLine -> "java"
The InstallJava
function or its close relative
ReinstallJava
has an option called
CommandLine
:
CommandLine -> "cmd" use the specified command line to launch the Java runtime, instead of "java"
Some examples of that is
InstallJava[]
InstallJava[CommandLine -> "java"]
InstallJava[CommandLine -> "java --Xmx1024m"]
The source code in
$InstallationDirectory/SystemFiles/Links/JLink/Kernel/InstallJava.m
indicates that if CommandLine
is not used, it will
uses Mathematica's own Java ToFileName[{getJLinkAppDir[],
"JLink.app", "Contents", "MacOS"}, "JavaApplicationStub"]
.
If CommandLine -> "java"
is used, make sure it's
the right version:
In[8]:= Needs["JLink`"]
ReinstallJava[CommandLine->"java"]
LoadJavaClass["java.lang.System"]
java`lang`System`getProperty["java.version"]
Out[9]= LinkObject[java -classpath "/Applications/Mathematica.app/SystemFiles/Links/JLink/JLink.jar" -Xdock:name=J/Link -Xmx256m -Djava.system.class.loader=com.wolfram.jlink.JLinkSystemClassLoader com.wolfram.jlink.Install -init "/tmp/m00000347291",166,4]
Out[10]= JavaClass[java.lang.System,<>]
Out[11]= 1.6.0_65
If the output of getProperty["java.version"]
is not
consistent with JAVA_HOME
, or if
LoadJavaClass["java.lang.System"]
issues errors, there
must be some problem.
See the attached notebook containing these testing code.
Methods for starting Mathematica
open -a Mathematica
If I start Mathematica with open -a Mathematica
from command line, which would lead Mathematica to inherit
JAVA_HOME
set in .bashrc
, I get the
correct JAVA_HOME
value
In[1]:= Import["!echo $JAVA_HOME", "Text"]
Out[1]= "/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/\
Home"
In[2]:= Environment["JAVA_HOME"]
Out[2]= "/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/\
Home"
as well as correct version of Java:
In[16]:= Needs["JLink`"]
ReinstallJava[CommandLine -> "java"]
LoadJavaClass["java.lang.System"]
java`lang`System`getProperty["java.version"]
Out[17]= LinkObject["'/Applications/Mathematica.app/SystemFiles/Links/JLink/JLink.app/Contents/MacOS/JavaApplicationStub' -init \"/tmp/m00000847291\"", 219, 4]
Out[18]= JLink`JavaClass["java.lang.System", 0, {JLink`JVM["vm1"],JLink`JVM["vm2"]}, 1, "java`lang`System`", False, True]
Out[19]= "1.6.0_65"
At the same time Oracle JDK 1.7 and 1.8 are installed on the system.
Double clicking "/Applications/Mathematica.app"
If I start Mathematica by double clicking "/Applications/Mathematica.app" in Finder or a link to it in Dock,
ReinstallJava[CommandLine -> "java"]
LoadJavaClass["java.lang.System"]
issues a LinkObject::linkn
error, and
Environment["JAVA_HOME"]
returns
$Failed
:
In[1]:= Needs["JLink`"]
ReinstallJava[CommandLine->"java"]
LoadJavaClass["java.lang.System"]
java`lang`System`getProperty["java.version"]
Out[2]= LinkObject[java -classpath "/Applications/Mathematica.app/SystemFiles/Links/JLink/JLink.jar" -Xdock:name=J/Link -Xmx256m -Djava.system.class.loader=com.wolfram.jlink.JLinkSystemClassLoader com.wolfram.jlink.Install -init "/tmp/m00000155721",125,4]
During evaluation of In[1]:= LinkObject::linkn: Argument LinkObject[java -classpath "/Applications/Mathematica.app/SystemFiles/Links/JLink/JLink.jar" -Xdock:name=J/Link -Xmx256m -Djava.system.class.loader=com.wolfram.jlink.JLinkSystemClassLoader com.wolfram.jlink.Install -init "/tmp/m00000155721",125,4] in LinkReadyQ[LinkObject[java -classpath "/Applications/Mathematica.app/SystemFiles/Links/JLink/JLink.jar" -Xdock:name=J/Link -Xmx256m -Djava.system.class.loader=com.wolfram.jlink.JLinkSystemClassLoader com.wolfram.jlink.Install -init "/tmp/m00000155721",125,4]] has an invalid LinkObject number; the link may be closed. >>
During evaluation of In[1]:= LinkObject::linkn: Argument LinkObject[java -classpath "/Applications/Mathematica.app/SystemFiles/Links/JLink/JLink.jar" -Xdock:name=J/Link -Xmx256m -Djava.system.class.loader=com.wolfram.jlink.JLinkSystemClassLoader com.wolfram.jlink.Install -init "/tmp/m00000155721",125,4] in LinkConnectedQ[LinkObject[java -classpath "/Applications/Mathematica.app/SystemFiles/Links/JLink/JLink.jar" -Xdock:name=J/Link -Xmx256m -Djava.system.class.loader=com.wolfram.jlink.JLinkSystemClassLoader com.wolfram.jlink.Install -init "/tmp/m00000155721",125,4]] has an invalid LinkObject number; the link may be closed. >>
During evaluation of In[1]:= LinkObject::linkn: Argument LinkObject[java -classpath "/Applications/Mathematica.app/SystemFiles/Links/JLink/JLink.jar" -Xdock:name=J/Link -Xmx256m -Djava.system.class.loader=com.wolfram.jlink.JLinkSystemClassLoader com.wolfram.jlink.Install -init "/tmp/m00000155721",125,4] in LinkReadyQ[LinkObject[java -classpath "/Applications/Mathematica.app/SystemFiles/Links/JLink/JLink.jar" -Xdock:name=J/Link -Xmx256m -Djava.system.class.loader=com.wolfram.jlink.JLinkSystemClassLoader com.wolfram.jlink.Install -init "/tmp/m00000155721",125,4]] has an invalid LinkObject number; the link may be closed. >>
During evaluation of In[1]:= General::stop: Further output of LinkObject::linkn will be suppressed during this calculation. >>
During evaluation of In[1]:= InstallJava::fail: A link to the Java runtime could not be established. >>
During evaluation of In[1]:= LoadJavaClass::fail: Java failed to load class java.lang.System. >>
Out[3]= $Failed
Out[4]= java`lang`System`getProperty[java.version]
I don't fully understand what causes the
LinkObject::linkn
error and its possible relation to
JAVA_HOME
. My guess is this is due to
JAVA_HOME
not being correctly set for Mathematica and
and somewhere in the processing an implied and incorrect Java home
is used, possibly computed by
$ /usr/libexec/java_home
/Library/Java/JavaVirtualMachines/jdk1.8.0.jdk/Contents/Home
For both ways of starting Mathematica,
ReinstallJava[] (* notice there is NO CommandLine -> "java" used *)
LoadJavaClass["java.lang.System"]
works. This is probably expected as CommandLine ->
Automatic
seems to lead Mathematica to use its own Java
$InstallationDirectory/SystemFiles/Links/JLink/JLink.app/Contents/MacOS/JavaApplicationStub
.
The logic controlling this can be found in source file
$InstallationDirectory/SystemFiles/Links/JLink/Kernel/InstallJava.m
.
So if you have multiple Java installed and if
/usr/libexec/java_home
finds the wrong version of Java
home directory for Mathematica (i.e. not 1.6.*)
$ /usr/libexec/java_home
/Library/Java/JavaVirtualMachines/jdk1.8.0.jdk/Contents/Home
you'll need to start Mathematica with open -a
Mathematica
.
Wrapper application OpenMathematicaAppFromCLIWithJava1.6.app made with Automator
If you prefer double clicking an icon on Dock than opening
terminal and typing open -a Mathematica
, you can
create an application equivalent to setting JAVA_HOME
and open -a Mathematica
and put a link to it in
Dock.
1) Start /Applications/Automator.app by double clicking it;
2) Choose "Application" and press button "Choose";
3) In "Variables" input field, type "Run Shell Script", and double click it;
4) In the RHS window, replace the default content 'cat' with
export JAVA_HOME=$(/usr/libexec/java_home -v 1.6*)
open -a "/Applications/Mathematica.app"
5) Save it somewhere as a standalone application. I chose name
OpenMathematicaAppFromCLIWithJava1.6.app
;
6) Optionally, you can make the icon of
OpenMathematicaAppFromCLIWithJava1.6.app
same as
Mathematica.app
's by clicking "Get Info" in the
context menu of the two applictions, and copy the icon in the top
left part of the pop-up window by selecting the icon by clicking on
it and Cmd-C and
Cmd-V;
7) Drag OpenMathematicaAppFromCLIWithJava1.6.app
onto Dock to create a link to it;
8) Start Mathematica by clicking the icon on Dock, and verify
that Environment["JAVA_HOME"]
and
getProperty[java.version]
behave correctly.
Configuring IDEs (virtually Eclipse and IntelliJ IDEA)
In IDEs such as Eclipse and IntelliJ IDEA, it's actually easier
to use multiple versions of JDK, and different versions for
different projects/modules. It's fairly easy to find the related
documentation. My understanding is IDEs' JDK version does not have
to be same as command-line java
. They are basically
different and unrelated Java development environments.
A relatively more complex issue is, as Eclipse and IntelliJ IDEA themselves are Java applications, what JVM are they running off of? And do you possibly want to start them using Oracle Java?
Here are some information:
IntelliJ IDEA
Selecting the JDK version the IDE will run under.
Eclipse
(This part about Eclipse is a drat and needs verification.)
Method 1: -vm
in
Eclipse.ini
Add something like
-vm /Library/Java/JavaVirtualMachines/jdk1.7.0_45.jdk/Contents/Home/
at the end of eclipse.ini.
Method 2: shell script + Automator application
Make a shell script that takes care of JAVA_HOME
and JVM:
#!/bin/sh
export JAVA_HOME=$(/usr/libexec/java_home -v 1.7)
LAUNCHER_JAR=/Applications/eclipse/plugins/org.eclipse.equinox.launcher_1.2.0.v20110502.jar
java \
-showversion \
-XX:MaxPermSize=256m \
-Xms1024m \
-Xmx1024m \
-Xdock:icon=/Applications/eclipse/Eclipse.app/Contents/Resources/Eclipse.icns \
-XstartOnFirstThread \
-Dorg.eclipse.swt.internal.carbon.smallFonts \
-Dosgi.requiredJavaVersion=1.5 \
-jar $LAUNCHER_JAR
and then make a wrapper application using Automator.
Installing Oracle JDK from command-line
-
Download DMG
$ wget --no-cookies --no-check-certificate --header "Cookie: gpw_e24=http%3A%2F%2Fwww.oracle.com%2F; oraclelicense=accept-securebackup-cookie" "http://download.oracle.com/otn-pub/java/jdk/8u60-b27/jdk-8u60-macosx-x64.dmg"
-
Mount DMG:
$ hdiutil mount jdk-8u60-macosx-x64.dmg
-
Install
$ sudo installer -pkg /Volumes/JDK\ 8\ Update\ 60/JDK\ 8\ Update\ 60.pkg -dominfo LocalSystem $ sudo installer -pkg /Volumes/JDK\ 8\ Update\ 60/JDK\ 8\ Update\ 60.pkg -target LocalSystem