How can I make rJava use the newer version of java on osx?

17k views Asked by At

I am following this tutorial on rJava: http://cran.r-project.org/web/packages/helloJavaWorld/vignettes/helloJavaWorld.pdf

I have made all the files as specified in the tutorial and installed the helloJavaWorld package, but once I run the helloJavaWorld() function, it complains:

> helloJavaWorld()
Error in .jnew("HelloJavaWorld") :
  java.lang.UnsupportedClassVersionError: HelloJavaWorld : Unsupported major.minor version 52.0

So I tried to check the java version that rJava is using:

.jinit()
jvm = .jnew("java.lang.System")
jvm.props = jvm$getProperties()$toString()
jvm.props <- strsplit(gsub("\\{(.*)}", "\\1", jvm.props), ", ")[[1]]
jvm.props

 [1] "java.runtime.name=Java(TM) SE Runtime Environment"
 [2] "sun.boot.library.path=/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Libraries"
 [3] "java.vm.version=20.65-b04-466.1"
 [4] "awt.nativeDoubleBuffering=true"
 [5] "gopherProxySet=false"
 [6] "mrj.build=11M4716"
 [7] "java.vm.vendor=Apple Inc."
 [8] "java.vendor.url=http://www.apple.com/"
 [9] "path.separator=:"
[10] "java.vm.name=Java HotSpot(TM) 64-Bit Server VM"
[11] "file.encoding.pkg=sun.io"
[12] "user.country=US"
[13] "sun.os.patch.level=unknown"
[14] "java.vm.specification.name=Java Virtual Machine Specification"
[15] "user.dir=/private/tmp"
[16] "java.runtime.version=1.6.0_65-b14-466.1-11M4716"
[17] "java.awt.graphicsenv=apple.awt.CGraphicsEnvironment"
[18] "java.endorsed.dirs=/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home/lib/endorsed"
[19] "os.arch=x86_64"
[20] "java.io.tmpdir=/var/folders/5d/44ctbbln4dsflgzxph1dm8wr0000gn/T/"
[21] "line.separator=\n"
[22] "java.vm.specification.vendor=Sun Microsystems Inc."
[23] "os.name=Mac OS X"
[24] "sun.jnu.encoding=MacRoman"
[25] "java.library.path=.:/Users/kaiyin/Library/Java/Extensions:/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/java"
[26] "java.specification.name=Java Platform API Specification"
[27] "java.class.version=50.0"
[28] "sun.management.compiler=HotSpot 64-Bit Tiered Compilers"
[29] "os.version=10.10"
[30] "http.nonProxyHosts=local|*.local|169.254/16|*.169.254/16"
[31] "user.home=/Users/kaiyin"
[32] "user.timezone="
[33] "java.awt.printerjob=apple.awt.CPrinterJob"
[34] "file.encoding=MacRoman"
[35] "java.specification.version=1.6"
[36] "java.class.path=/Library/Frameworks/R.framework/Versions/3.1/Resources/library/rJava/java/boot:/Library/Frameworks/R.framework/Versions/3.1/Resources/library/helloJavaWorld/java"
[37] "user.name=kaiyin"
[38] "java.vm.specification.version=1.0"
[39] "java.home=/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home"
[40] "sun.arch.data.model=64"
[41] "user.language=en"
[42] "java.specification.vendor=Sun Microsystems Inc."
[43] "awt.toolkit=apple.awt.CToolkit"
[44] "java.vm.info=mixed mode"
[45] "java.version=1.6.0_65"
[46] "java.ext.dirs=/Users/kaiyin/Library/Java/Extensions:/Library/Java/Extensions:/System/Library/Java/Extensions:/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home/lib/ext"
[47] "sun.boot.class.path=/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Classes/jsfd.jar:/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Classes/classes.jar:/System/Library/Frameworks/JavaVM.framework/Frameworks/JavaRuntimeSupport.framework/Resources/Java/JavaRuntimeSupport.jar:/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Classes/ui.jar:/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Classes/laf.jar:/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Classes/sunrsasign.jar:/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Classes/jsse.jar:/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Classes/jce.jar:/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Classes/charsets.jar"
[48] "java.awt.headless=true"
[49] "java.vendor=Apple Inc."
[50] "file.separator=/"
[51] "java.vendor.url.bug=http://bugreport.apple.com/"
[52] "sun.io.unicode.encoding=UnicodeLittle"
[53] "sun.cpu.endian=little"
[54] "mrj.version=1070.1.6.0_65-466.1"
[55] "socksNonProxyHosts=local|*.local|169.254/16|*.169.254/16"
[56] "ftp.nonProxyHosts=local|*.local|169.254/16|*.169.254/16"
[57] "sun.cpu.isalist="

It looks like it uses java 1.6 (preinstalled on OSX), but I compiled the HelloJavaWorld class with java 1.8, which leads to the question: How can I make rJava use the newer version of java?

Output of R CMD javareconf:

Java interpreter : /usr/bin/java
Java version     : 1.8.0_25
Java home path   : /Library/Java/JavaVirtualMachines/jdk1.8.0_25.jdk/Contents/Home/jre
Java compiler    : /usr/bin/javac
Java headers gen.: /usr/bin/javah
Java archive tool: /usr/bin/jar
Non-system Java on OS X

trying to compile and link a JNI progam
detected JNI cpp flags    : -I$(JAVA_HOME)/../include -I$(JAVA_HOME)/../include/darwin
detected JNI linker flags : -L$(JAVA_HOME)/lib/server -ljvm
clang -I/Library/Frameworks/R.framework/Resources/include -DNDEBUG -I/Library/Java/JavaVirtualMachines/jdk1.8.0_25.jdk/Contents/Home/jre/../include -I/Library/Java/JavaVirtualMachines/jdk1.8.0_25.jdk/Contents/Home/jre/../include/darwin -I/usr/local/include -I/usr/local/include/freetype2 -I/opt/X11/include    -fPIC  -Wall -mtune=core2 -g -O2  -c conftest.c -o conftest.o
clang -dynamiclib -Wl,-headerpad_max_install_names -undefined dynamic_lookup -single_module -multiply_defined suppress -L/usr/local/lib -o conftest.so conftest.o -L/Library/Java/JavaVirtualMachines/jdk1.8.0_25.jdk/Contents/Home/jre/lib/server -ljvm -F/Library/Frameworks/R.framework/.. -framework R -Wl,-framework -Wl,CoreFoundation


JAVA_HOME        : /Library/Java/JavaVirtualMachines/jdk1.8.0_25.jdk/Contents/Home/jre
Java library path: $(JAVA_HOME)/lib/server
JNI cpp flags    : -I$(JAVA_HOME)/../include -I$(JAVA_HOME)/../include/darwin
JNI linker flags : -L$(JAVA_HOME)/lib/server -ljvm
Updating Java configuration in /Library/Frameworks/R.framework/Resources
Done.

Content of /Library/Frameworks/R.framework/Versions/3.1/Resources/etc/javaconf

## Versions from settings when configure was run
: ${JAVA_HOME=}
: ${JAVA_CPPFLAGS=~autodetect~}
: ${JAVA_LD_LIBRARY_PATH=~autodetect~}
: ${JAVA_LIBS=~autodetect~}

Content of /Library/Frameworks/R.framework/Versions/3.1/Resources/etc/ldpaths

➜  etc  cat ldpaths
: ${JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.8.0_25.jdk/Contents/Home/jre}
: ${R_JAVA_LD_LIBRARY_PATH=${JAVA_HOME}/lib/server}
if test -n ""; then
: ${R_LD_LIBRARY_PATH=${R_HOME}/lib:}
else
: ${R_LD_LIBRARY_PATH=${R_HOME}/lib}
fi
if test -n "${R_JAVA_LD_LIBRARY_PATH}"; then
  R_LD_LIBRARY_PATH="${R_LD_LIBRARY_PATH}:${R_JAVA_LD_LIBRARY_PATH}"
fi
## This is DYLD_FALLBACK_LIBRARY_PATH on Darwin (OS X) and LD_LIBRARY_PATH elsewhere
if test -z "${DYLD_FALLBACK_LIBRARY_PATH}"; then
  DYLD_FALLBACK_LIBRARY_PATH="${R_LD_LIBRARY_PATH}"
else
  DYLD_FALLBACK_LIBRARY_PATH="${R_LD_LIBRARY_PATH}:${DYLD_FALLBACK_LIBRARY_PATH}"
fi
export DYLD_FALLBACK_LIBRARY_PATH
4

There are 4 answers

2
qed On

I solved the problem by installing from the latest source package on RForge: http://www.rforge.net/rJava/files/

cd /tmp
wget http://www.rforge.net/rJava/snapshot/rJava_0.9-7.tar.gz
R CMD INSTALL rJava_0.9-7.tar.gz

In R:

> library(helloJavaWorld)
Loading required package: rJava
> helloJavaWorld()
[1] "Hello from java!"
0
nadia On

Here is a solution that worked pretty good for me:

  1. In the terminal run: R CMD javareconf

  2. Get the JAVA_HOME path and the Java library path from the output Example

JAVA_HOME : /Library/Java/JavaVirtualMachines/jdk1.8.0_65.jdk/Contents/Home/jre Java library path: $(JAVA_HOME)/lib/server JNI cpp flags : -I$(JAVA_HOME)/../include -I$(JAVA_HOME)/../include/darwin JNI linker flags : -L$(JAVA_HOME)/lib/server -ljvm Updating Java configuration in /Library/Frameworks/R.framework/Resources

  1. Then, make sure you don't have an open instance of RStudio. We'll create an alias that will open RStudio with the correct path to your latest java version. Run this in your commend line

alias rstudio="DYLD_FALLBACK_LIBRARY_PATH=/Library/Java/JavaVirtualMachines/jdk1.8.0_65.jdk/Contents/Home/jre/lib/server open -a RStudio"

  1. Type rstudio in your terminal

  2. Done! Rstudio will open pointing to the right java version

2
Lizzie Silver On

I had a similar problem, but this solution didn't work for me. I eventually got it working, but now I'm not sure which of the things I changed solved the problem. Here's what I did:

  1. I added the following lines to my .bash_profile:

    export JAVA_HOME="/Library/Java/JavaVirtualMachines/jdk1.8.0_25.jdk/Contents/Home/jre"
    export LD_LIBRARY_PATH=/Library/Java/JavaVirtualMachines/jdk1.8.0_25.jdk/Contents/Home/jre/lib/server 
    export PATH=$PATH:$JAVA_HOME/bin
    
  2. I set my java.home option and my DYLD_FALLBACK_LIBRARY_PATH environmental variable in R:

    options(java.home="/Library/Java/JavaVirtualMachines/jdk1.8.0_25.jdk")
    Sys.setenv(DYLD_FALLBACK_LIBRARY_PATH="/Library/Java/JavaVirtualMachines/jdk1.8.0_25.jdk/Contents/Home/jre/lib/server/")
    
  3. I re-installed Apple's version of Java 1.6 just in case, as per this issue thread: https://github.com/s-u/rJava/issues/37

  4. I reconfigured R's java settings. In Bash: R CMD javareconf
  5. I ran R as root, and then installed rJava from source, directly from RForge. In Bash: sudo R. Then in the R session: install.packages('rJava',,'http://www.rforge.net/').

Installing from source was crucial to making rJava pick up on R's new Java settings. When I didn't install from source, rJava would install ok, but it would continue to use JRE 1.6. You can check which JRE rJava uses by running:

library(rJava)
.jinit()
.jcall("java/lang/System", "S", "getProperty", "java.runtime.version")

Running R as root was crucial to making rJava install correctly from the RForge source. When I tried to run install.packages('rJava',,'http://www.rforge.net/') as User, I got the following error messages:

  • If running R in the command line, rJava would not install correctly:

    checking JNI data types... configure: error: One or more JNI types differ from the corresponding native type. You may need to use non-standard compiler flags or a different compiler in order to fix this.
    ERROR: configuration failed for package ‘rJava’
    
  • If running R as an application from Finder, rJava would install, but not load:

    > library(rJava) 
    Error : .onLoad failed in loadNamespace() for 'rJava', details:  
    call: dyn.load(file, DLLpath = DLLpath, ...) 
    error: unable to load shared object '/Library/Frameworks/R.framework/Versions/3.2/Resources/library/rJava/libs/rJava.so': dlopen(/Library/Frameworks/R.framework/Versions/3.2/Resources/library/rJava/libs/rJava.so, 6): 
    Library not loaded: @rpath/libjvm.dylib 
    Referenced from: /Library/Frameworks/R.framework/Versions/3.2/Resources/library/rJava/libs/rJava.so 
    Reason: image not found 
    Error: package or namespace load failed for ‘rJava’
    

Hopefully this answer will save someone else some time!

Edited to add: Two of my professors followed these instructions and ran into the following issue: rJava would work when running R in the command line, but would fail to load when running RStudio or the default Mac R app.

Joe Ramsey figured out the solution. He writes:

Apparently RStudio grumbles about having to use the default user/directory that Apple uses to open applications.

This article describes it: http://jeromyanglim.tumblr.com/post/34221143729/how-to-run-rstudio-from-the-command-line-on-osx

[To fix the issue] You go to the command line and type: open -a rstudio or open -a R

Edit number two: I just installed rJava on one of the school computers, running Ubuntu 14.04.4 LTS (64-bit). I was able to install rJava when running R as root. However, when I then tried to run R as user and load the package, I got a brand new loading error:

> library(rJava)
Error : .onLoad failed in loadNamespace() for 'rJava', details:
    call: dyn.load(file, DLLpath = DLLpath, ...)
    error: unable to load shared object '/home/lizziesilver/R/x86_64-pc-linux-gnu-library/3.2/rJava/libs/rJava.so':
    libjvm.so: cannot open shared object file: No such file or directory
  Error: package or namespace load failed for ‘rJava’

I checked the directory; rJava.so definitely existed. It turned out that I didn't have the right permissions for it:

...$ ls -l /home/lizziesilver/R/x86_64-pc-linux-gnu-library/3.2/rJava/libs/rJava.so
-rwxr-xr-x 1 root root 353325 Feb 26 16:58 /usr/lib/R/library/rJava/libs/rJava.so

So I changed the permissions: sudo chmod -R a+rX /home/lizziesilver/R/x86_64-pc-linux-gnu-library/3.2/rJava/

Then reconfigured R's java settings:

export LD_LIBRARY_PATH=/usr/lib/jvm/java-8-oracle/lib/amd64:/usr/lib/jvm/java-8-oracle/jre/lib/amd64/server
sudo R CMD javareconf

Now rJava loads, even when running R as user instead of root!

rJava: the package that keeps on giving (config errors)

4
Andrew On

There's a lot of conflicting info about rJava on SO. My concern with a lot of these answers was that once you start monkeying with the JAVA_HOME variables, you run the risk of borking your Java install completely -- the solution can be worse than the disease. Here's a quick rundown of 'do no harm' things you can do if you are having rJava problems.

1) in the terminal, run R CMD javareconf. This is a script written by R Core that will "Detect current Java setup and update the corresponding configuration in R." Take a look at the internals here.

2) re-install rJava from source. install.packages("rJava", type = "source").

3) Open R from the command line. Load rJava. Open RStudio from the command line (directions). Load rJava. Do you get the same error? If not, great - you're getting warmer! You've isolated your problem to an issue with RStudio, not R itself.

4) There's some sort of issue with RStudio and rJava that relates to - actually, you know what, I'm not even going to try to finish that sentence, because frankly it's above my pay grade. Dynamic libraries something something.

There are a bunch of writeups (here, here, here, and here) on the web about this. My favorite title was "the rJava nightmare."

Your mileage may vary, but this SO answer was all I needed to get RStudio to play nice -- one line of code on the terminal, and all it does is creates a symbolic link. No changes to permissions, no modification of environment variables - just a simple symlink.

If that doesn't do it for you, I'd suggest reading the linked blog posts above before you start copy/pasting the multitude of this worked for me answers littered across SO.