2014-11-06 26 views
1

我正在尝试运行JRI的示例并且失败,这里是示例的链接。 http://blog.comsysto.com/2013/07/10/java-r-integration-with-jri-for-on-demand-predictions/JRI的问题

import org.rosuda.JRI.Rengine; 
import org.rosuda.JRI.REXP; 

public class HelloRWorld { 
    Rengine rengine; // initialized in constructor or autowired 

    public void helloRWorld() { 
     rengine.eval(String.format("greeting <- '%s'", "Hello R World")); 
     REXP result = rengine.eval("greeting"); 
     System.out.println("Greeting from R: "+result.asString()); 
    } 
} 

这是控制台给我的错误。

Exception in thread "main" java.lang.NullPointerException 
    at org.roulette.games.HelloRWorld.helloRWorld(HelloRWorld.java:10) 
    at org.roulette.games.HelloRWorld.main(HelloRWorld.java:17) 

据我所知,我有外部JRI 2014-10-19 jar正确附加到项目。 我安装了R 3.1.2,并安装了rJava 0.9-6软件包。

第10行是“rengine.eval(String.format(”greeting < - '%s'“,”Hello R World“));”。

第17行是“hello.helloRWorld();”。

请让我知道,如果你有一个想法,为什么它抛出这些异常.... :)

+0

那么,你从来没有初始化rengine。 – 2014-11-06 22:25:38

+0

你的意思是罐子!?谢谢!我会尝试,但我不会因为它没有被导入... – 2014-11-06 22:27:32

+0

不。这是java,rengine从null开始,直到您为其指定一个有效的引用。例如,'Rengine rengine = Rengine.getMainEngine();' – 2014-11-06 22:32:33

回答

1

试试这个:是的作品:你有几个错误

package stackoverflow; 

import org.rosuda.JRI.REXP; 
import org.rosuda.JRI.Rengine; 
/** 
* 
* @author yschellekens 
*/ 
public class StackOverflow { 

    public static void main(String[] args) throws Exception { 
    String[] Rargs = {"--vanilla"}; 
    Rengine rengine = new Rengine( Rargs, false, null); 
    rengine.eval("greeting <- '%Hello R World'"); 
     REXP result = rengine.eval("greeting"); 
     System.out.println("Greeting from R: "+result.asString()); 
    } 
} 

通知,包括不包含主类,并且不创建合适的构造函数。

1

有两种不同的方法来连接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

0

你应该使用以下命令导出LD_LIBRARY_PATH

export LD_LIBRARY_PATH=/usr/lib/jvm/jre/lib/amd64:/usr/lib/jvm/jre/lib/amd64/default 

,并从内部R中进行

install.packages("rJava") 

这肯定会让你的REngine成功的从你的java应用程序中运行