Javaweb多次调用Rengine re=new Rengine(args, false, new TextConsole()); 报错

来源:互联网 发布:网店的营销策略数据 编辑:程序博客网 时间:2024/05/21 22:27

问题场景

按照前文rJava的安装与测试-不用每次设置VM参数‘-Djava.library.path’所述弄好了JRI,但是在项目里重复调用Rengine re = new Rengine(args, false, new TextConsole());这段代码时,项目会停止响应或者报错。

解决方式

既然重复调用不行那就让项目初始化时只调取一次Rengine实例就好了,采用单例模式即可。另外将你对应的jri.dll(我的在D:\programFile\R\R-3.4.1\library\rJava\jri\x64目录下)文件放入Tomcat的bin目录下。

调用方式:

/** * 调用R脚本生成克隆进化图 * java与R互调思路见我的博客:http://blog.csdn.net/sand_clock/article/details/78031010 * @param filePath      作图的地址 * @param imagePath     保存图片的地址 * @param rPath         R脚本的路径 * @return              作图是否成功 */public static boolean createClonePic(String filePath, String imagePath, String rPath) {    Rengine re = SingleRengine.getRegineInstance();       if (!re.waitForR()) {           System.out.println("Cannot load R");           return false;       }       System.out.println("开始执行脚本里的函数");       //调用R脚本,注意R路径里不要用'\\',要用'/'       re.assign("fn", rPath);       //用source命令将脚本中的函数加载到R环境中,后续可以直接调用       re.eval("source(fn)");       //调用有参函数       //在R里给变量赋值用于传参       re.assign("filePath", filePath);       re.assign("imagePath", imagePath);       REXP rex = re.eval("VolinPlot(filePath, imagePath)");       if (rex == null) {        return false;       }       RBool success = rex.asBool();       if (success.isTRUE()) {        return true;       }    return false;}

单例类:

package rjava;import org.rosuda.JRI.RMainLoopCallbacks;import org.rosuda.JRI.Rengine;import java.awt.*;import java.io.BufferedReader;import java.io.InputStreamReader;/** * Created on 2017/9/29 * Author: youxingyang. */public class SingleRengine {    //私有的静态内部类 构造类时是原子操作    private static class SingleRengineIn {    private static final SingleRengine singleRengine = new Rengine(null, false, new TextConsole());    }    public static SingleRengine getInstance() {        return SingleRengineIn.singleRengine;    }    private SingleRengine() {}    private static class TextConsole implements RMainLoopCallbacks {        @Override        public void rWriteConsole(Rengine re, String text, int oType) {            System.out.print(text);        }        @Override        public void rBusy(Rengine re, int which) {            System.out.println("rBusy(" + which + ")");        }        @Override        public String rReadConsole(Rengine re, String prompt, int addToHistory) {            System.out.print(prompt);            try {                BufferedReader br =new BufferedReader(new InputStreamReader(System.in));                String s = br.readLine();                return (s == null || s.length() == 0) ? s : s +"\n";            }catch (Exception e) {                System.out.println("jriReadConsole exception: " + e.getMessage());            }            return null;        }        @Override        public void rShowMessage(Rengine re, String message) {            System.out.println("rShowMessage \"" + message + "\"");        }        @Override        public void rFlushConsole(Rengine re) {        }        @Override        public void rLoadHistory(Rengine re, String filename) {        }        @Override        public void rSaveHistory(Rengine re, String filename) {        }        @SuppressWarnings("deprecation")        @Override        public String rChooseFile(Rengine re, int newFile) {            FileDialog fd =new FileDialog(new Frame(), (newFile == 0) ?"Select a file" :"Select a new file",                    (newFile ==0) ? FileDialog.LOAD : FileDialog.SAVE);            fd.show();            String res =null;            if (fd.getDirectory() != null)                res = fd.getDirectory();            if (fd.getFile() != null)                res = (res ==null) ? fd.getFile() : (res + fd.getFile());            return res;        }    }}