Lehrstuhl fuer Rechnerorientierte Statistik und Datenanalyse Uni Augsburg  
Institut Forschung Lehre Mitarbeiter News Allgemeines Research Staff Software
rJava

About rJava

printable form

About rJava

Note: The official rJava development page has moved to rJava project at RForge.net

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 nightly builds pages.

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.

What's new?
2006/10/10 - The current rJava version is 0.4-11

2006/09/11 - rJava 0.4-8 released (includes JRI 0.3-2). Starting with this release, JRI is only compiled if R was built as a shared library (which is a necessary requirement anyway). Please always see CRAN for the latest version.

2006/05/08 - rJava 0.4-2 released.
This version is the last of a succession of (almost daily) updates that were reflected on CRAN. The main new feature is that JRI is now included in the rJava distribution. JRI library and classes are installed in the jri subdirectory of the installed rJava package. The installation of JRI can be disabled by using --disable-jri. Another new flag is --enable-debug which enables very verbatim debugging output.

2006/04/17 - rJava 0.3-8 released.
Adds a handful features: allows dynamic change of the class path for some VMs, supports additional parameters to be passed to the VM (see .jinit), adds suport for a few more types and fixes a few minor bugs - see NEWS file inside. Update is recommended to all users, especially if you plan to use multiple packages relying on rJava.

2006/01/30 - rJava 0.3-6 released.
Mostly bugfixes (Win2k compatibility, memory management, debugging) and added --enable-threads option (necessary for AWT with R GUI on OS X, but still experimental). Update strongly recommended to all users.

2005/12/21 - rJava 0.3-3 released.
Arrays no longer need an explicit cast and arbitrarily nested arrays are supported as well (thanks to Kurt Hornik for very useful feedback)

2005/12/19 - rJava 0.3-2 is now the first public release of the 0.3 series. The object references now use external pointers and automatically free Java objects if the reference was garbage-collected in R. There is no longer need for .jfree. Support for easy array construction was added in the form of the .jarray function.

2005/12/03 - rJava 0.2-3 released and rJava is now available on CRAN.

2005/09/03 - rJava 0.2-0 is now the first release of the "next generation" which uses S4 objects as the representation of Java objects in R. This gives us a bit more flexibility and some additional sanity checks. If you wrote a code that relies on the contents of the reference objects, you will probably need to replace $ by @. Nevertheless the direct use of slots is discouraged as it can change in the future. Also the new convenience API using the $ operator was introduced.

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:

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 u ssee 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.

Last updated: 2006/09/11


[Institut] [Forschung] [Lehre] [Mitarbeiter] [News] [Allgemeines] [Software]