This is my sample R file :
# filename: sample.R
main <- function (){
returnStringValue <- "ignore"
return (returnStringValue)
}
main()
Now I am trying to source on the file on Rserve using java:
import org.rosuda.REngine.REXP;
import org.rosuda.REngine.Rserve.RConnection;
public class RServeTest {
static RConnection rcon;
public static void main(String[] args) {
try {
String fileName = "sample.R";
String filePath = "/filepath/";
try {
rcon = new RConnection();
}
catch(Exception e){
System.out.println("Error Connecting: "+e);
}
String rCode = "source(\""+filePath+fileName+"\")";
System.out.println("Rscript call on file: "+rCode);
REXP r = rcon.parseAndEval("try(eval(parse(text="+rCode+")),silent=TRUE)");
System.out.println("r object: "+r.asString());
if (r.inherits("try-error"))
System.err.println("Error: "+r.asString());
else
System.out.println("Executed R code successfully.");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
which gives me the following error:
Rscript call on file: source("/home/maverick/Documents/sem3/agent code/sample.R")
Error: Error in eval(expr, envir, enclos) : object 'ignore' not found
How do I handle string values getting returned from the R code, without affecting the errors getting caught?
For eg:
Let's say I have a bug in my code:
main <- function (){
returnStringValue <- "ignore"
# error
var1+1
return (returnStringValue)
}
main()
The java code should log :
Rscript call on file: source("/filepath/sample.R")
Error: Error in main() : object 'var1' not found
rather than logging :
org.rosuda.REngine.Rserve.RserveException: eval failed, request status: error code: 127
at org.rosuda.REngine.Rserve.RConnection.eval(RConnection.java:233)
at RServeTest.main(RServeTest.java:39)
The error can be solved by returning a json object from R, instead of a string value. Here is how I solved this error:
Java code to source R file and run main() function:
import org.rosuda.REngine.REXP;
import org.rosuda.REngine.Rserve.RConnection;
public class RServeTest {
static RConnection rcon;
public static void main(String[] args) {
try {
String fileName = "sample.R";
// Note: Change filename for testing different samples
String filePath = "/filepath/";
try {
rcon = new RConnection();
}
catch(Exception e){
System.out.println("Error Connecting: "+e);
}
String rCode = "source(\""+filePath+fileName+"\")";
System.out.println("Rscript call on file: "+rCode);
// Source file
REXP r0 = rcon.parseAndEval("try(eval(parse(text="+rCode+")),silent=TRUE)");
// Run main() function
REXP r = rcon.parseAndEval("try(eval(parse(text=main())),silent=TRUE)");
System.out.println("\n--------- with try error ------------");
if (r.inherits("try-error"))
System.out.println("Error: "+r.asString());
else
System.out.println("Executed R code successfully."+"r object: "+r.asString());
System.out.println("\n--------- without try error ------------");
System.out.println("R output :"+rcon.eval("main()").asString());
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
R code Sample 1:
main <- function (){
returnStringValue <- "ignore"
return (returnStringValue)
}
Results:
Rscript call on file: source("/filepath/sample1.R")
--------- with try error ------------
Error: Error in eval(expr, envir, enclos) : object 'ignore' not found
--------- without try error ------------
R output :ignore
Without try-error
method gives us the return string value we wanted, but if there is an error, as in the case below, it returns eval failed
which can only be logged using the try-error
method (please see sample 2).
R code Sample 2:
main <- function (){
# error
var1+1
returnStringValue <- "ignore"
return (returnStringValue)
}
Results:
Rscript call on file: source("/filepath/sample2.R")
--------- with try error ------------
Error: Error in main() : object 'var1' not found
--------- without try error ------------
org.rosuda.REngine.Rserve.RserveException: eval failed, request status: error code: 127
at org.rosuda.REngine.Rserve.RConnection.eval(RConnection.java:233)
at RServeTest.main(RServeTest.java:43)
The aforementioned issue can be dealt with, by returning a json object from R instead of a string value. Here are sample codes and results:
R code Sample 3:
require('rjson')
main <- function (){
# error
var1+1
returnStringValue <- "ignore"
returnJsonObject <- toJSON(returnStringValue)
return (returnJsonObject)
}
Results:
Rscript call on file: source("/filepath/sample3.R")
--------- with try error ------------
Error: Error in main() : object 'var1' not found
--------- without try error ------------
org.rosuda.REngine.Rserve.RserveException: eval failed, request status: error code: 127
at org.rosuda.REngine.Rserve.RConnection.eval(RConnection.java:233)
at RServeTest.main(RServeTest.java:43)
R code Sample 4:
require('rjson')
main <- function (){
returnStringValue <- "ignore"
returnJsonObject <- toJSON(returnStringValue)
return (returnJsonObject)
}
Results:
Rscript call on file: source("/filepath/sample4.R")
--------- with try error ------------
Executed R code successfully.r object: ignore
--------- without try error ------------
R output :"ignore"
Hence, from sample 3 and 4 you can see that we have achieved our desired output.