4.1 Rserve与Java的跨平台通信

问题

Java怎么调用R?

Java怎么调用R?

引言

当前主流的异构跨平台通信组件Apache Thrift已经火遍大江南北,支持15种编程语言,但是到目前为止还没有加入R语言。要让R实现跨平台的通信,就只能从R的社区(CRAN)中找方案,像rJava、RCpp、rpy都是2种语言结合的方案,这些方案类似地会把R引擎加载到其他语言内存环境。这类方案的优点是高效,缺点是紧耦合,扩展受限,接口程序无法重用。

Rserve给了我们一种新的选择,它是抽象R语言网络接口,基于TCP/IP协议实现与多语言之间的通信。Rserve支持R语言与其他语言通信,通过C/S结构的程序调用,支持C/C++、Java、PHP、Python、Ruby、Nodejs等。 Rserve支持远程连接、用户认证、文件传输等功能。我们可以设计R作为后台服务引擎,处理统计建模、数据分析、绘图等的任务。本节我们就来体验Rserve与Java的跨平台通信。

4.1.1 Rserve安装

本节使用的系统环境是:

  • Linux Ubuntu 12.04.2 LTS 64bit server
  • R: 3.0.1 x86_64-pc-linux-gnu
  • IP 192.168.1.201

注:Rserve同时支持Win7环境和Linux环境,由于Rserve主要用来做通信服务器,建议使用Linux环境。

Rserve的安装过程如下:

~ R                              # 启动R程序
> install.packages("Rserve")  # 安装Rserve
~ R CMD Rserve                 # 在命令行启动Rserve服务器
~ ps -aux|grep Rserve        #查看进程
conan     7142  0.0  1.2 116296 25240 ?        Ss   09:13   0:00 /usr/lib/R/bin/Rserve

~ netstat -nltp|grep Rserve   #查看端口
tcp       0      0 127.0.0.1:6311          0.0.0.0:*        LISTEN      7142/Rserve

这时Rserve服务器已经启动,端口是6311。127.0.0.1表示只接受来自IP为127.0.0.1的请求访问,即只允许本地应用访问。如果我们想远程访问 Rserve,就需要开启远程模式,这就需要在启动命令时增加参数 –RS-enable-remote:

~ kill -9 7142                        #杀掉刚才的Rserve守护进程
~ R CMD Rserve --RS-enable-remote  #以远程模式启动Rserve
~ netstat -nltp|grep Rserve         #查看端口
tcp        0      0 0.0.0.0:6311         0.0.0.0:*           LISTEN      7173/Rserve

0 0.0.0 说明不限IP访问了,我们接下来就可以从远程来访问Rserve了。

4.1.2 用Java远程连接Rserve

Java程序在Win7中通过EclipseIDE工具直接运行,让Java远程连接Linux系统上的Rserve服务器。Win7环境是:

  • JAVA :Oracle SUN JDK 1.6.0_45 64bit
  • Eclipse: Juno Service Release 2
  • IP: 192.168.1.13

Rserve所在Linux服务器的IP为 192.168.1.201。

1. 下载Java客户端JAR包

通过链接( http://www.rforge.net/Rserve/files/),下载Java客户端JAR包REngine.jar 和 RserveEngine.jar。通过这两个Jar包,就可以实现Java和Rserve的通信了。

  • REngine.jar : 用于R和Java数据类型的映射
  • RserveEngine.jar : 用于Rserve的通信程序

这两个类库说明,可以查看官方的javadoc文件,网址是 http://rforge.net/org/doc/。这两个JAR包是Java编译后的二进制文件,没有提供源代码文件。

2. 在Eclipse中创建Java工程

在Eclipse中新建Java工程,并加载Jar包环境中,加载后如图4-1所示。

Eclipse中的Java工程

3. Java编程实现

下面我们来写一个Java的类Demo1.java,完成Java远程调用Rserve服务器的实现,Demo1.java中包括2个方法。

  • main()方法:是Java程序启动的入口,实例化一个demo对象,然后调用callRserve()方法。
  • callRserve()方法:创建远程访问Rserve的socket连接,以字符串的方式向Rserve服务器发送两条R的语句,在Rserve上计算并返回结果,最后在Java中输出结果。

Demo1.java代码如下。

package org.conan.r.rserve;

import org.rosuda.REngine.REXP;
import org.rosuda.REngine.REXPMismatchException;
import org.rosuda.REngine.Rserve.RConnection;
import org.rosuda.REngine.Rserve.RserveException;

public class Demo1 {

    /**
     * Main方法用于启动Java应用
     */
    public static void main(String[] args) throws RserveException, REXPMismatchException {
        Demo1 demo = new Demo1();
        demo.callRserve();
    }

    /**
     * 访问Rserve
     */
    public void callRserve() throws RserveException, REXPMismatchException {
        RConnection c = new RConnection("192.168.1.201");   //创建访问连接
        REXP x = c.eval("R.version.string");                //执行一条R的语句
        System.out.println(x.asString());                   //在Java中打印返回结果

        double[] arr = c.eval("rnorm(10)").asDoubles();     //执行rnorm(10)语句
        for (double a : arr) {                              //在Java中循环打印返回结果
            System.out.print(a + ",");
        }
    }
}

运行结果

R version 3.0.1 (2013-05-16)
1.7695224124757984,-0.29753038160770323,0.26596993631142246,1.4027325257239547,-0.30663565983302676,-0.17594309812158912,0.10071253841443684,0.9365455161259986,0.11272119436439701,0.5766373030674361,

通过Rserve我们就非常简单地实现了Java和R的通信,更准确地说,是Java访问Rserve服务器,实现了基于TCP/IP的通信。我们解决了通信的问题后,就可以发挥想象,把R更广泛地用起来了。本节只是简单地介绍了Rserve的安装和启动,关于Rserve服务器详细的使用和配置,请查看5.1节。

results matching ""

    No results matching ""