R 3.4, rJava, macOS and even more mess ;)

So, you want to have rJava (e.g. rJava_0.9-8.tar.gz) inside your fresh, new installation of R 3.4 and you are running macOS. There are bad news and good news ;)

Bad news. It will fail with default clang that comes with XCode. You need something better here, something with support for OpenMP. And you can get it following way

# make sure to create some place where you want to have it (I, personally, put stuff into ~/opt)
> mkdir ~/opt
> cd ~/opt
> curl http://releases.llvm.org/4.0.1/clang+llvm-4.0.1-x86_64-apple-darwin.tar.xz \
-o clang+llvm-4.0.1-x86_64-apple-darwin.tar.xz
> tar xf clang+llvm-4.0.1-x86_64-apple-darwin.tar.xz

Now, make sure to install gfortran. I am using version from this location: GFortran.

Once you have it, make sure to install most recent JDK from Oracle. You can find it here: JavaSE.

After you have your Java installed, make sure to do following (double check that everything is OK so far)

> R --version
R version 3.4.1 (2017-06-30) -- "Single Candle"
Copyright (C) 2017 The R Foundation for Statistical Computing
Platform: x86_64-apple-darwin15.6.0 (64-bit)

R is free software and comes with ABSOLUTELY NO WARRANTY.
You are welcome to redistribute it under the terms of the
GNU General Public License versions 2 or 3.
For more information about these matters see
http://www.gnu.org/licenses/.
> /usr/libexec/java_home -V
Matching Java Virtual Machines (3):
    1.8.0_144, x86_64:	"Java SE 8"	/Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Home
    1.8.0_111, x86_64:	"Java SE 8"	/Library/Java/JavaVirtualMachines/jdk1.8.0_111.jdk/Contents/Home
    1.7.0_80, x86_64:	"Java SE 7"	/Library/Java/JavaVirtualMachines/jdk1.7.0_80.jdk/Contents/Home

/Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Home

# Make sure to put following line inside you ~/.profile
# export JAVA_HOME=$(/usr/libexec/java_home -v 1.8.0_144)
# close and re-open Terminal session. Now, you should be able to see:
> echo $JAVA_HOME
/Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Home
/usr/libexec/java_home
/Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Home

Make sure to enable your JDK for JNI

> sudo vi /Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Info.plist

# make sure to replace
#<array>
#  <string>CommandLine</string>
#</array>
# with
#<array>
#  <string>CommandLine</string>
#  <string>JNI</string>
#</array>

Now, it’s time to configure R. Make sure to run following command.

!! (note that we change JAVA_HOME to JRE) !!

> JAVA_HOME=${JAVA_HOME}/jre
> sudo R CMD javareconf \
JAVA_HOME=${JAVA_HOME} \
JAVA=${JAVA_HOME}/../bin/java \
JAVAC=${JAVA_HOME}/../bin/javac \
JAVAH=${JAVA_HOME}/../bin/javah \
JAR=${JAVA_HOME}/../bin/jar \
JAVA_LIBS="-L${JAVA_HOME}/lib/server -ljvm" \
JAVA_CPPFLAGS="-I${JAVA_HOME}/../include -I${JAVA_HOME}/../include/darwin"

Note! It looks like R CMD javareconf doesn’t update all the flags, make sure that file: /Library/Frameworks/R.framework/Versions/3.4/Resources/etc/Makeconf contains following entries:

JAVA_LIBS="-L${JAVA_HOME}/lib/server -ljvm" \
JAVA_CPPFLAGS="-I${JAVA_HOME}/../include -I${JAVA_HOME}/../include/darwin"

You should have your Java and R linked together. It’s time to add support for clang that you have just installed few steps above.

Let’s say your clang is in your home dir. Here: /Users/user_name/opt/clang+llvm-4.0.1-x86_64-apple-macosx10.9.0/

Make sure, to add following file (~/.R/Makevars – more info can be found here: R for Mac OS X FAQ and here: R Installation and Administration)

CLANG=/Users/user_name/opt/clang+llvm-4.0.1-x86_64-apple-macosx10.9.0
CC=$(CLANG)/bin/clang
CXX=$(CLANG)/bin/clang++
CXX1X=$(CLANG)/bin/clang++
CXXFLAGS=-I$(CLANG)/include

Also, make sure to modify file:

/Library/Frameworks/R.framework/Versions/3.4/Resources/etc/Makeconf

inside this file, make sure that line “LDFLAGS” reads

LDFLAGS = -L/usr/local/lib -L/Users/user_name/opt/clang+llvm-4.0.1-x86_64-apple-macosx10.9.0/lib -lomp

You can confirm that it works by calling:

# you can confirm that by calling
> R CMD config --ldflags
-fopenmp -L/usr/local/lib 
-L/Users/user_name/opt/clang+llvm-4.0.1-x86_64-apple-macosx10.9.0/lib 
-lomp -F/Library/Frameworks/R.framework/.. -framework R 
-lpcre -llzma -lbz2 -lz -licucore -lm -liconv

Now, it’s time to get rJava. Simply download it, and install it:

> curl "https://cran.r-project.org/src/contrib/rJava_0.9-8.tar.gz" -o rJava_0.9-8.tar.gz
> R CMD INSTALL rJava_0.9-8.tar.gz
* installing to library ‘/Library/Frameworks/R.framework/Versions/3.4/Resources/library’
* installing *source* package ‘rJava’ ...
...
...
*** installing help indices
** building package indices
** testing if installed package can be loaded
* DONE (rJava)

And you can now test it. Let’s say you have (in your working directory) following layout

utils/
└── RUsingStringArray.java

and file RUsingStringArray.java contains

package utils;

public class RUsingStringArray {
  public String [] createArray() {
    System.out.println("Creating empty array");
    return new String[0];
  }
}

You can compile it and run it in R

> javac utils/*.java
> export CLASSPATH=`pwd`
> export JAVA_HOME=$(/usr/libexec/java_home -v 1.8.0_144)/jre
> R
> library(rJava)
> .jinit()
> obj <- .jnew("utils.RUsingStringArray")
> s <- .jcall(obj, returnSig="[Ljava/lang/String;", method="createArray")
> .jcall(obj, returnSig="I", method = "arrayLen", s)
Class: class [Ljava.lang.String;
[1] 0
>

Leave a comment

Your comment