Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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!

like image 368
Chris Avatar asked May 09 '14 10:05

Chris


2 Answers

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);
like image 120
user3741031 Avatar answered Sep 26 '22 14:09

user3741031


Very old question, but I would add that considering RServe as an alternative is often attractive. The set-up is less involved (in my opinion) and the interface is almost identical.

Detailed tutorial given here. (note that this is a waybackmachine (archive) link as the original link became stale - it might be a little slow to load, but should stay working).

This has the additional benefits that if you ever want to make calls to R from parallel threads of Java you can do so.

like image 39
kabdulla Avatar answered Sep 23 '22 14:09

kabdulla