R4.0 with Java 14 inside macOS 10.15.4
As usual, there are some issues with new Java releases (14) and R4.0. If you want to run rJava package inside R you have to do few things.
First, make sure you are using Java 14 as default inside terminal session. Inside ~/.profile or ~/.zshrc add this line
export JAVA_HOME=$(/usr/libexec/java_home -v 14)
Once it’s done, you have to make sure to install XCode – you can find it here: XCode. We will need that. XCode contains SDK that is used while R reconfigures itself – it will try to compile small, JNI based, code.
After XCode is installed, make sure to modify this file: /Library/Frameworks/R.framework/Versions/4.0/Resources/etc/Makeconf.
Try to locate the line that reads
CPPFLAGS = -I/usr/local/include
and replace it with line
CPPFLAGS = -isysroot /Applications/XCode/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/ -I/usr/local/include
Note! Make sure this is just one line inside Makeconf!
Now, you are ready to configure R. Simply call this one
> 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
That’s it. You can now install and use rJava package.
Let’s say you have this simple code
.
`-- src
`-- somepackage
`-- StringTest.java
and the content of file is
package somepackage;
public class StringTest {
public String changeString(String str) {
return "I have changed the string: " + str;
}
public static void main(String [] arg) {
System.out.println(new StringTest().changeString("Hello"));
}
}
You can compile it following way.
> javac -d target src/somepackage/StringTest.java > java -cp target somepackage.StringTest I have changed the string: Hello > export CLASSPATH=`pwd`/target
and then, use it inside R.
> R version 4.0.0 (2020-04-24) -- "Arbor Day"
Copyright (C) 2020 The R Foundation for Statistical Computing
Platform: x86_64-apple-darwin17.0 (64-bit)
...
...
...
> install.packages('rJava')
...
...
> library(rJava)
> .jinit()
> obj <- .jnew("somepackage.StringTest")
> s <- .jcall(obj, returnSig="Ljava/lang/String;", method="changeString", "Hello")
> print(s)
[1] "I have changed the string: Hello"
> s <- .jcall(obj, returnSig="V", method="main", c("Hello", "Hello") )
I have changed the string: Hello