Java code can be built and run using the package rJava. JRI.jar in the rJava package includes the necessary classes for interacting with R from within Java. In fact rJava comes with two systems for doing this. Rengine is a lower level interface, and is therefore less safe to use. REngine provides much of the same functionality, but has better error checking. This article will focus on REngine, as it is the recommended API. Note that JGR.jar (from the JGR package) also includes the REngine classes, so if that is the only part of JRI that you need, you may build your Java project against it.
The basic structure for a Java package is much the same as any other package.
-package_name DESCRIPTION -inst -java package_name.jar -man -R zzz.R
Like and R package. There are 'man' and 'R' directories which contain the R documentation and R code respectively. The DESCRIPTION file is the same as for any other package, and should have rJava
in the Required list.
Unlike many R packages there is an 'inst' directory. This indicates to R that when the package is built, anything in the 'inst' folder should be copied verbatim into the package root directory. When rJava looks for java code, it will try to load any .jar files in the 'java' directory. These files may be named anything.
To add your jar to the classpath, two statements should be added to the .First.lib
(or on.load
) function in zzz.R.
.First.lib <- function(libname, pkgname) { .jpackage(pkgname) .jengine(TRUE) }
The .jpackage
call adds all .jar files in the 'java' directory of your package to the classpath. The '.jengine' call starts the REngine, so that your Java code can call R functions. If your Java code does not import REngine (or Rengine), then this statement is not needed. Also, if your package requires Deducer, it is also not needed, as the engine is already started.
R commands can be executed from Java using the the JRIEngine
class.
JRIEngine en; try{ en = new JRIEngine(org.rosuda.JRI.Rengine.getMainEngine()); catch(Exception e){} REXP oneToTenR = en.parseAndEval(“1:10”);
This evaluates the R statement 1:10
and then assigns it to oneToTenR
which is of class REXP
. REXP
objects are Java representations of R expressions. REXP
objects can be converted to something that Java can more readily manipulate using a series of conversion methods. For example, we can convert oneToTenR
into and array of doubles using the asDoubles
method.
double[] oneToTenJava; try{ oneToTen = oneToTenR.asDoubles(); catch(Exception e){}
The following table enumerates the conversion functions, and what they convert too.
Function | Converts to | Note |
---|---|---|
REXP.asInteger() | int | factors/logicals* ok |
REXP.asDouble() | double | factors/integers/logical** ok |
REXP.asString() | String | factors ok |
REXP.asStrings() | String[] | factors ok |
REXP.asDoubles() | double[] | factors/integers/logical** ok |
REXP.asBytes() | byte[] | |
REXP.asIntegers() | int[] | factors/logicals* ok |
REXP.asList().at(int index) | REXP | for R lists and data.frames |
*NA = -2147483648
**NA=Double.longBitsToDouble(0x7ff00000000007a2L);
If your package uses Deducer, there is a convenience method (Deducer.eval
) for executing R statements.
//using Deducer wrapper REXP rVariable = Deducer.eval(“names(Prestige)”); String[] prestigeNames; try{ prestigeNames = rVariable.asStrings() } catch (REXPMismatchException e) {}
Also there is a useful method for executing R commands as if the user typed them into the console:
Deducer.execute(“print(‘I like ponies’)”);
You will need to compile your Java code into package_name.jar
. You may need to compile it against JRI.jar, JGR.jar and/or Deducer.jar (found in the rJava, JGR and Deducer packages respectively), depending on which classes you use in your code. This can be accomplished in any number of ways using any Java IDE. Below is a desciption of how to do it using the command line.
1. Make a new directory with the following structure:
-src -package_name *.java <------All of your java source code Deducer.jar JGR.jar JRI.jar
2. Then, in the src directory execute
javac -target 1.4 -source 1.4 -d . -classpath JRI.jar:JGR.jar:deducer.jar package_name/*.java jar fc package_name.jar package_name/*.class
If you are using Windows, you may need to change the first line to:
javac -target 1.4 -source 1.4 -d . -classpath JRI.jar\JGR.jar\deducer.jar package_name/*.java
Then copy the newly created package_name.jar
to the java
directory of your package.
Auto generated Documentation on REngine
and the REXP
class can be found Here.Now that you have the basics of dealing with R objects in Java, the next step is to build a GUI dialog using the Swing toolkit.