I am trying to run Rscript from JAVA code. I am able to do so. Now I am trying to run same JAVA code from a Spring MVC project and using Wildfly 9 to run the project. For the first time when I am trying to execute JAVA code (to run Rscript) is working fine and giving correct result, but on running 2nd time it is giving error and Wildfly stops running. Below is the error that I am getting:
A fatal error has been detected by the Java Runtime Environment:
Internal Error (0xc0000029), pid=6768, tid=8456
JRE version: Java(TM) SE Runtime Environment (7.0_75-b13) (build 1.7.0_75-b13)
Java VM: Java HotSpot(TM) Client VM (24.75-b04 mixed mode, sharing windows-x86 )
Problematic frame:
C [ntdll.dll+0xa096a]
Failed to write core dump. Minidumps are not enabled by default on client versions of Windows
The JAVA code is below:
package com.test.util;
import org.rosuda.JRI.Rengine;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class RunRScript {
private static final Logger logger = LoggerFactory
.getLogger(RunRScript.class);
public void runScript() {
// Create an R vector in the form of a string.
String javaVector = "c(1,2,3,4,5)";
// Start Rengine.
Rengine engine = new Rengine(new String[] { "--no-save" }, false, null);
// The vector that was created in JAVA context is stored in 'rVector' which is a variable in R context.
engine.eval("rVector=" + javaVector);
//Calculate MEAN of vector using R syntax.
engine.eval("meanVal=mean(rVector)");
//Retrieve MEAN value
double mean = engine.eval("meanVal").asDouble();
//Print output values
logger.info("Mean of given vector is=" + mean);
}
}
I am using Windows 8 64-bit and R-2.15.0. Please let me know if my question is not clear or you need any other information. Thanks in advance.
You can't call JRI engine with that code. According to the documentation, JRI doesn't allow more that one engine instance per JVM, so you shouldn't create more than one engine.
This line:
Must be called only once. You have to ensure that only one engine is started in your JVM.
On the other hand, JRI uses by default the same environment to handle all the calls (eval, assign, etc...) so the rest of your code must be synchronized, otherwise you can suffer race conditions every time two different threads are executing eval methods.
If you have trouble getting it working, you can replace JRI by Rserve, that doesn't need JRI library loaded into the JVM and allow concurrency (each thread must use its own RConnection).
But with Rserve you should setup your engine only once, as well as using JRI.
You can use a @PostConstruct method:
You can do the same with JRI:
And then reuse the same
Rengine
instance in each call (make sure you synchronize the access to this instance).You have more examples in this repo