问题
I am trying to run an example of JRI and being unsuccessful, here is a link to the example. http://blog.comsysto.com/2013/07/10/java-r-integration-with-jri-for-on-demand-predictions/
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());
   }
}
This is the error the console gives me.
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)
As far as I know I have the external JRI 2014-10-19 jar attached to the project correctly. I have R 3.1.2 installed and I have the rJava 0.9-6 package installed.
Line 10 is "rengine.eval(String.format("greeting <- '%s'", "Hello R World"));".
And Line 17 is "hello.helloRWorld();".
Please Let me know if you have an idea as to why it's throwing these exceptions.... :)
回答1:
Try this: is works:
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());
   }
}
Notice that you had several errors, including not including a main class, and not creating the proper constructor.
回答2:
There are two different approach to connect Java and R.
If you want to use JRI, you have to start your java program using the JVM parameter -Djava.library.path pointing at the folder that contains JRI library.
For instance:
$JAVA_HOME/bin/java  -Djava.library.path=/app/vendor/R/lib/R/library/rJava/jri/ -jar target/myapp.jar
If you have trouble finding JRI installation directory, try to look for the JRI SO library:
find / -name "libjri.*"
In addition, make sure you have created R_HOME and LD_LIBRARY_PATH in your environment:
- R_HOME: Pointing to your local R installation (Ej: /Library/Frameworks/R.framework/Resources)
 - LD_LIBRARY_PATH: Pointing to R lib directory as well as JRI directory (EJ: $LD_LIBRARY_PATH:/app/vendor/R/lib/R/lib:/app/vendor/R/lib/R/bin)
 
Here is an example:
@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);
}
On the other hand, if you want to use Rserve, you need to start Rserve in a separate process, and then create a RConnection from your java process.
For example:
        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 is the path to Rserv conf file and rexe is the full path to R executable.
For instance, in my MacOS computer I can start Rserve executing this line:
/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"
This command outputs something like this:
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.
Make sure to specify "--slave" parameter when you start Rserve.
If you want to see more examples, I have a demo project that use both approaches, JRI and RServe, in my github:
https://github.com/jfcorugedo/RJavaServer
回答3:
You should export LD_LIBRARY_PATH by using below command
export LD_LIBRARY_PATH=/usr/lib/jvm/jre/lib/amd64:/usr/lib/jvm/jre/lib/amd64/default
And from within R execute
install.packages("rJava")
That for sure will make your REngine works successfully from your java applicaition
来源:https://stackoverflow.com/questions/26790505/problems-with-jri