有两种不同的方法来连接Java和R.
如果你想使用JRI,你必须开始使用JVM参数-Djava.library.path
在包含JRI库的文件夹指向你的Java程序。
例如:
$JAVA_HOME/bin/java -Djava.library.path=/app/vendor/R/lib/R/library/rJava/jri/ -jar target/myapp.jar
如果你有麻烦找JRI安装目录下,试图去寻找JRI SO库:
find/-name "libjri.*"
此外,请确认你已经创建R_HOME和LD_LIBRARY_PATH在你的环境中:
- R_HOME:指向本地R安装(Ej:/Library/Frameworks/R.framework/Resources)
- LD_LIBRARY_PATH:指向R lib目录以及JRI目录(EJ:$ LD_LIBRARY_PATH:/ app/vendor/R/LIB/R/lib目录:/应用/供应商/ R/lib中/ R /箱)
下面是一个例子:
@Test
public void testMeanFunction() {
// just making sure we have the right version of everything
if (!Rengine.versionCheck()) {
System.err.println("** Version mismatch - Java files don't match library version.");
fail(String.format("Invalid versions. Rengine must have the same version of native library. Rengine version: %d. RNI library version: %d", Rengine.getVersion(), Rengine.rniGetVersion()));
}
// Enables debug traces
Rengine.DEBUG = 1;
System.out.println("Creating Rengine (with arguments)");
// 1) we pass the arguments from the command line
// 2) we won't use the main loop at first, we'll start it later
// (that's the "false" as second argument)
// 3) no callback class will be used
engine = REngine.engineForClass("org.rosuda.REngine.JRI.JRIEngine", new String[] { "--no-save" }, null, false);
System.out.println("Rengine created...");
engine.parseAndEval("rVector=c(1,2,3,4,5)");
REXP result = engine.parseAndEval("meanVal=mean(rVector)");
// generic vectors are RVector to accomodate names
assertThat(result.asDouble()).isEqualTo(3.0);
}
在另一方面,如果你想使用Rserve,您需要在独立进程中启动Rserve,然后从你的java进程创建一个RConnection。
例如:
if(LOGGER.isInfoEnabled()) {
LOGGER.info("Starting RServe process...");
}
ProcessBuilder builder = new ProcessBuilder("/bin/sh", "-c", String.format("echo 'library(Rserve);Rserve(FALSE,args=\"--no-save --slave --RS-conf %s\")'|%s --no-save --slave", rserveConf, rexe));
builder.inheritIO();
Process rProcess = builder.start();
if(LOGGER.isInfoEnabled()) {
LOGGER.info("Waiting for Rserve to start...");
}
int execCodeResult = rProcess.waitFor();
if(execCodeResult != SUCCESS_CODE) {
LOGGER.error(String.format("Unexpected error code starting RServe: %d", execCodeResult));
} else {
LOGGER.error("RServe started successfully");
}
if(LOGGER.isInfoEnabled()) {
LOGGER.info("Opening connection to RServe daemon....");
}
REngine engine = new RConnection();
if(LOGGER.isInfoEnabled()) {
LOGGER.info(String.format("Obtaining R server version: %d", ((RConnection)engine).getServerVersion()));
}
//Perform some engine.parseAndEval("....");
rserveConf是通向Rserv CONF文件和rexe是至R可执行文件的完整路径。
举例来说,在我的MacOS电脑我可以开始Rserve执行这一行:
/bin/sh -c "echo 'library(Rserve);Rserve(FALSE,args=\"--slave --RS-conf /Users/me/Documents/test/rserve.conf\")'|/Library/Frameworks/R.framework/Versions/3.2/Resources/bin/exec/R --no-save --slave"
此命令的输出是这样的:
Starting Rserve:
/Library/Frameworks/R.framework/Resources/bin/R CMD /Library/Frameworks/R.framework/Versions/3.2/Resources/library/Rserve/libs//Rserve --slave
Rserv started in daemon mode.
确保指定 “--slave” 参数当你启动Rserve。
如果你想看到更多的例子,我有使用这两种方法,JRI和RServe,在我github上演示项目:
https://github.com/jfcorugedo/RJavaServer
那么,你从来没有初始化rengine。 – 2014-11-06 22:25:38
你的意思是罐子!?谢谢!我会尝试,但我不会因为它没有被导入... – 2014-11-06 22:27:32
不。这是java,rengine从null开始,直到您为其指定一个有效的引用。例如,'Rengine rengine = Rengine.getMainEngine();' – 2014-11-06 22:32:33