|
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.
2021-09-24 - rJava 1.0-5 released. This update is only important to JDK-17 users and make sure you read NEWS file as some existing packages may no longer work with JDK-17 due to some major changes.
2021/04/29 - rJava 1.0-4 released. This release fixes a possible segafult in .jfields() when used on class objects (also indirectly in J() API).
2021/04/15 - rJava 1.0-2 released. This release improves string handling between R and Java for characters outside of the Unicode BMP.
2021/04/12 - rJava 1.0-1 released. This is a major new release, the main feature is the introduction of custom class loaders for R package authors. R packages using Java are encouraged to use this new facility to avoid class clashes with other Java packages.
2021/02/04 - rJava 0.9-14 released. Mostly fixes in JRI compilations.
2020/07/06 - rJava 0.9-13 released. Minor fixes and increase default stack size.
2020/03/23 - rJava 0.9-12 released. Strongly recommended for macOS users, required for Catalina. Invalid JAVA_HOME settings are now reported. Also includes some minor bug-fixes.
...
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/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.
|
|
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:
I | integer |
D | double (numeric) |
J | long (*) |
F | float (*) |
V | void | Z | boolean |
C | char (integer) |
B | byte (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.
|