Java调用R脚本无法生成JSON文件,直接运行R脚本正常
问题:Java调用R脚本无法生成JSON文件,直接运行R脚本正常
我尝试通过Java程序执行R脚本,但脚本中需生成的JSON文件未成功生成;但直接在R环境中运行该脚本时,JSON文件可正常生成。
使用环境:R Version 4.2.3、Ubuntu 20.04.6
Java程序
package com.demo; import org.rosuda.JRI.Rengine; public class R { public static void main(String[] args) { System.out.println("Start"); Rengine r = new Rengine(new String[] {"--vanilla"}, false, null); r.eval("source(\"/home/ubuntu20/Documents/RProjectCheck/Sample.r\")"); System.out.println("Done"); } }
R脚本(Sample.r)
attach(iris) c5func<-function() { myTryCatch <- function(expr) { warn <- err <- NULL value <- withCallingHandlers( tryCatch(expr, error=function(e) { err <<- e NULL }), warning=function(w) { warn <<- w invokeRestart("muffleWarning") }) list(value=value, warning=warn, error=err) } depvar<-"Species" model<-C50::C5.0(Species ~ Sepal.Length+Sepal.Width+Petal.Length+Petal.Width, data=iris ,trials=1, rules=TRUE, control=C50::C5.0Control(subset=FALSE, winnow=FALSE, noGlobalPruning=TRUE, CF=0.25, minCases=2)) model library(caret) confmatcode<-paste("confusionMatrix(predict(model, type='class', iris),",depvar,")",collapse="", sep="") if(is.null(myTryCatch(eval(parse(text=confmatcode)))$error)) { confmattrain<-eval(parse(text=confmatcode)) write(jsonlite::serializeJSON(confmattrain), file="/home/ubuntu20/Documents/RProjectCheck/GeneratedFiles/ConfusionMatrix.json") } } c5func() rm(list=ls()) gc()
可能的原因及解决思路
- 权限问题:Java进程运行用户可能没有目标目录
/home/ubuntu20/Documents/RProjectCheck/GeneratedFiles/的写入权限。直接运行R时用的是当前用户,而Java可能以其他用户身份执行(如服务用户)。可以通过ls -l /home/ubuntu20/Documents/RProjectCheck/GeneratedFiles/查看权限,或在R脚本中添加print(Sys.info()["user"])对比两种执行方式的用户差异,必要时调整目录权限。 - 依赖包加载异常:
--vanilla参数会禁用R的启动配置,可能导致包加载路径异常。直接运行R时的默认配置可能自动加载了依赖,而Java调用时缺失。可以去掉--vanilla参数测试,或在R脚本开头显式检查并加载依赖,比如在library(caret)前添加if (!requireNamespace("caret", quietly = TRUE)) stop("需要安装caret包")。 - 错误未被暴露:脚本中的
myTryCatch捕获了错误但未输出,可能confmatcode执行出错导致未进入JSON写入分支。可以在if的else分支添加print(myTryCatch(eval(parse(text=confmatcode)))$error),或在Java中调用r.getLastError()获取R的错误信息,排查具体执行故障。 - R引擎初始化问题:确保Rengine成功启动,可在Java代码中添加判断:
避免在引擎未就绪时执行脚本。if (!r.waitForR()) { System.out.println("R引擎启动失败"); return; } - 工作目录差异:Java调用R时的工作目录可能与直接运行R时不同,可在R脚本开头添加
setwd("/home/ubuntu20/Documents/RProjectCheck/")固定工作目录,或打印getwd()确认路径是否正确。
内容的提问来源于stack exchange,提问作者user2664380
相关产品推荐
相关产品推荐

