Search code examples
javarsingletonjri

Java-R bridge "JRI" error: R is already initialized


I'm using JRI as a calculation slave for statistics from within Java. R computations are required from time to time, but not too frequently. Thus, i decided to create a wrapper method for the computation which creates a new REngine instance and also closes it by the end. Everything works like a charm when calling the method the first time. Unfortunately, calling it a second time triggers the error "R is already initialized".

Initialization:

private static Rengine createEngineInstance(){

        //Initialise R Engine. 
        Rengine re=new Rengine (new String [] {"--vanilla"}, false, new CallbackListener());

        //Wait until REngine-thread is ready
        if (!re.waitForR())
        {
            System.err.println ("Cannot load R. Is the environment variable R_HOME set correctly?");
            System.exit(1);
        }
        return re;
}

Wrapper method:

public static void performR(){

    //Create instance of R engine
    Rengine re = createEngineInstance();

    //Perform some R operations
    re.eval("...");

    re.end();

}

Obviously, the REngine instance is not terminated correctly. Thus, I need to know: 1) Is there a chance to terminate the REngine and create a new instance later again? How does this work correctly? I know that it is impossible to run multiple R threads at the same time with JRI, but this is not what I'm aiming for. 2) If this is not the case, I would create one instance using the Singleton pattern. How can I ensure in this case that the R session gets closed when the program terminates?

Your help is really appreciated! Thanks!


Solution

  • according to JRI Javadoc....

    Only one Rengine Instance can be used, and Rengine.end() function has some problems...

    you should not use code like this

    Rengine engine = new Rengine(new String[] {"--vanilla"}, false, null);
    

    you can use Rengine with this code

    Rengine engine = Rengine.getMainEngine();
    if(engine == null)
        engine = new Rengine(new String[] {"--vanilla"}, false, null);