rJava - Low-level R to Java interface
RForge.net

rJava

About rJava
GIT access
Download/Files
News
Check results
Package R docs

About rJava

What is rJava?
        

rJava is a simple R-to-Java interface. It is comparable to the .C/.Call C interface. rJava provides a low-level bridge between R and Java (via JNI). It allows to create objects, call methods and access fields of Java objects from R.

rJava release versions can be obtained from CRAN - usually install.packages("rJava") in R will do the trick. The current development version can be downloaded from the files section.

In a sense the inverse of rJava is JRI (Java/R Interface) which provides the opposite direction - calling R from Java. JRI is now shipped as a part of the rJava package, although it still can be used as a separate entity (especially for development). Currently rJava is used as a part of JGR, iPlots and JavaGD software/packages.

Please report any bugs or wishes related to rJava or JRI using Issues on GitHub.

What's new?
rJava source repository is now on GitHub and that is also the place to report bugs. The main page and builds are still on RForge.net.

2012/12/23 - rJava 0.9-6 released. Fixes Java parameter issue introduced in 0.9-5 on systems with headless mode (e.g. OS X).

2011/06/22 - rJava 0.9-0 released. This is a major upgrade that changes behavior of array references in low-level calls back to early 0.8 state as intedended by the original design. It should be more consistent now. We have had rJava 0.9-0 in RC state for a long time so hopefully all developers relying on rJava have checked their packages. For the full list of fixes and changes see NEWS.

2009/10/27 - rJava 0.8-0 released. Many new features mostly thanks to Romain Francois -- check the NEWS file for details.

2009/08/22 - rJava 0.7-0 released. Recommended update (includes bugfixes to fields handling, new support for with(), method/field auto-completion and more forgiving $ operator), includes JRI 0.5-0.

2008/09/22 - rJava 0.6-0 released. Adds support for Java serialization and R-side cache which enables Java objects to become persistent across sessions. See ?.jcache in R (or the online help) for details.

2007/11/05 - rJava 0.5-1 released. Fixes issues with Windows; and minor updates (see NEWS).

2007/08/22 - rJava 0.5-0 released. This is a major update featuring many new features and bugfixes. It sports a new custom class loader, much improved (and faster) field support, integration of all native Java types, automatic fall-back to static methods, infrastructure for writing Java packages easily (see .jpackage), support for custom convertors and call-backs. Please read the NEWS file for details.

2007/02/27 - rJava 0.4-14 (update is recommended to all users due to memory leak fixes), please use CRAN to get the latest release. The current development version is rJava 0.5-0 (available from here - see SVN access and download on the left). It is under heavy construction right now with many new features, so feel free to test-drive it if you want to be on the bleeding edge (it is a bit chatty as some debugging output is still enabled). Some of the highlights are memory profiler, intelligent class loader, easy Java package integration and callback support.

Installation

First, make sure you have JDK 1.4 or higher installed (some platforms require hgher version see R Wiki). On unix systems make sure that R was configured with Java support. If not, you can re-configure R by using R CMD javareconf (you may have to prepend sudo or run it as root depending on your installation - see R-ext manual A.2.2 for details). On Windows Java is detected at run-time from the registry.

rJava can be installed as any other R package from CRAN using install.packages('rJava'). See the files section in the left menu for development versions.

JRI is only compiled if supported, i.e. if R was configured as a framework or with --enable-R-shlib.

Documentation

If you want to run R within a Java application, please see the JRI pages for details. rJava allows you to use R code to create Java objects, call Java methods and pass data between R and Java. Most functions are already documented by the corresponding help pages in R, but here is a very basic crashcourse:

The following gives a quick guide to the use of rJava. If you have questions about installation, please visit the R Wiki - rJava package.

Let's start with some low-level examples. Remember, this is all essentially a JNI interface, so you may encounter new things if you used Java from high level only.

library(rJava)
.jinit() # this starts the JVM
s <- .jnew("java/lang/String", "Hello World!")
Ok, here we have our first Java object. It is equivalent to the Java line of (pseudo) code s = new java.lang.String("Hello World!"); The class name may look strange to casual Java users, but this is how JNI class names look like - slashes instead of dots. Also note that you must always refer to the full class name, because there is no import ... facility.

Next, we will call a simple method:

.jcall(s,"I","length")
[1] 12
This is equivalent to s.length(), but it is a bit more complex than expected. The main reason is that in JNI when looking up methods, you must supply the return type as well. So here we say that we want to call a method length on the object s with the return type I which means int. The table of JNI types is as follows:
Iinteger Ddouble (numeric) Jlong (*) Ffloat (*)
VvoidZboolean Cchar (integer) Bbyte (raw)
L<class>; Java object of the class <class> (e.g. Ljava/lang/Object;)
[<type> Array of objects of type <type> (e.g. [D for an array of doubles)
Not all types or combinations are supported, but most are. Note that the Java type short was sacrificed for greater good (and pushed to T), namely S return type specification in .jcall is a shortcut for Ljava/lang/String;. When passing parameters to methods, R objects are automatically converted where possible:
.jcall(s,"I","indexOf","World")
[1] 6
This is equivalent to s.indexOf("World") and the string parameter "World" is automatically converted into java.lang.String object and passed to Java. Note that you can equally pass Java object references as well. But before we do that, let us see how you can find a method signature if you're not sure. Let's say we want to know more about the concat method for our object s:
.jmethods(s,"concat")
[1] "public java.lang.String java.lang.String.concat(java.lang.String)"
We see that concat expects a string and returns a string, so we can just concatenate the string itself if we want:
.jcall(s,"Ljava/lang/String;","concat",s)
[1] "Hello World!Hello World!"
We are telling JNI that the return value will be of an object of the class java.lang.String (there is a convenience shotcut of S as well). The parameter evalString is by default set to TRUE (see help for .jcall), so you don't get a reference to the new string, but the actual contents instead.

There is a simple function .jstrVal that returns the content of a string reference or calls toString() method and returns the string:

print(s)
[1] "Java-Object: Hello World"
.jstrVal(s)
[1] "Hello World"
At the end, let us create some windows and buttons using AWT:
f <- .jnew("java/awt/Frame", "Hello")
b <- .jnew("java/awt/Button", "OK")
.jcall(f, "Ljava/awt/Component;", "add", .jcast(b, "java/awt/Component"))
.jcall(f,, "pack")
.jcall(f,, "setVisible", TRUE)
This should show a simple AWT window with an OK button inside. Note that we need to cast the button b into java/awt/Component, because the method signature needs to be matched precisely (call .jmethods(f, "add") to see the expected type). You can get rid of this window by calling .jcall(f,,"dispose").

Finally a note about the $ convenience operator. It provides an experimental, but simple way of writing code in Java style at the cost of speed. Taking the String example, you can achieve the same with:

s$length()
[1] 12
s$indexOf("World")
[1] 6
You simply use $ instead of .. This interface uses Java reflection API to find the correct method so it is much slower and may not be right (works for simple examples but may not for more complex ones). For now its use is discouraged in programs as it may change in the future. However, feel free to test it and report any issues with it.
(*) Note that there is no long or float type in R. Both are converted into numeric in R. In order to pass a numeric as either of the two back to Java, you will neeed to use .jfloat or .jlong functions to mark an object as belonging to one of those classes.