JavaからRを動かすrJavaを動かしたい

# はじめに
半年ほど前に新人さんから「RをJavaから動かしたい」と言われ、対応した際のメモ書きです。
プロセスキックしても良かったけど、**JRI** という **Java/R Interface** というモジュールがあったのでそれで対応してみた次第。

# What is rJava?

```
rJava is a simple R-to-Java interface.
It is comparable to the .C/.Call C interface.
rJava provides a low-level bridge between R and Java (via JNI).
It allows to create objects, call methods and access fields of Java objects from R.
```
http://www.rforge.net/rJava/index.html

要はJNI経由でRを呼び出すインターフェースですよと。
JNIを利用するのでdllファイルの設定とかあって多少面倒でした。


# JRI.jarの取得

JRI.jarを落としてきます。

RのGUIを起動してインストールコマンドを実行。

```
install.packages('rJava')
```

こうすると `C:\Program Files\R\R-3.3.1\library\rJava\` 配下にJARとDLLがダウンロードされます。
JARのバージョン管理が急にカオスになりそうなのですね。
JRI.jarだけはリポジトリ管理できそうです。

Gradle使いはこちら。

```groovy
// https://mvnrepository.com/artifact/org.nuiton.thirdparty/JRI
compile group: 'org.nuiton.thirdparty', name: 'JRI', version: '0.9-6'
```

Maven使いはこちら。

```xml
<dependency>
	<groupId>org.nuiton.thirdparty</groupId>
	<artifactId>JRI</artifactId>
	<version>0.9-6</version>
</dependency>
```

…なんですが、rJavaに含まれるdllファイルがどうしても必要です。
コマンドを叩かなくても本家サイトから落とすなど、個別対応を行う必要がありそうです。
http://www.rforge.net/rJava/files/


# dll設定

`jri.dll`を取ってきて、設定する。
`C:\Program Files\R\R-3.3.1\library\rJava\jri`のうちのどちらか。

64bitだと`x64`、32bitだと`i386`。

今回は実行する直下のフォルダに配備しました。
違うフォルダに配備する場合は、PATHを通してあげる必要があります。


# スタンドアロンアプリでの実行方法

PATHを通してやらないとダメ。

```sh:Windows環境の実行方法
set PATH=%PATH%;C:/Program Files/R/R-3.3.1/bin;C:/Program Files/R/R-3.3.1/bin/i386;C:\Program Files\R\R-3.3.1\library\rJava\jri\i386

java ^
-classpath "./classes;C:/Program Files/R/R-3.3.1/library/rJava/jri/JRI.jar" ^
example.MyTest
```

下の設定は無くても動きました。

```sh:不要な設定？
set R_DOC_DIR="C:/Program Files/R/R-3.3.1/doc"
set R_INCLUDE_DIR="C:/Program Files/R/R-3.3.1/include"
set R_SHARE_DIR="C:/Program Files/R/R-3.3.1/share"
```


# サーバアプリで動かす場合の実行方法

JRI.jarをWEB-INF/libに追加してあげる（MavenかGradleで管理していたら不要）。

また、jri.dllのパスも設定してあげる必要がある。
緑の実行ボタン＞実行の構成＞引数＞VM引数

```sh:実行時引数
-Djava.library.path="C:\Program Files\R\R-3.3.1\library\rJava\jri\i386"
```

を追加


# よく発生するエラー

## jri.dllのパスを通すのを忘れる

よくこんなエラーになる。

```java
Cannot find JRI native library!
Please make sure that the JRI native library is in a directory listed in java.library.path.

java.lang.UnsatisfiedLinkError: no jri in java.library.path
	at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1864)
	at java.lang.Runtime.loadLibrary0(Runtime.java:870)
	at java.lang.System.loadLibrary(System.java:1122)
	at org.rosuda.JRI.Rengine.<clinit>(Rengine.java:19)
	at example.MyTest(MyTest.java:11)
```

対応方法は、忘れずjri.dllのパス設定しましょう。


## Rのパスに変数を通していないと怒られる

上記を突破すると下記が出て来る。

```java
Cannot find JRI native library!
Please make sure that the JRI native library is in a directory listed in java.library.path.

java.lang.UnsatisfiedLinkError: C:\dll\jri.dll: Can't find dependent libraries
	at java.lang.ClassLoader$NativeLibrary.load(Native Method)
	at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1938)
	at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1854)
	at java.lang.Runtime.loadLibrary0(Runtime.java:870)
	at java.lang.System.loadLibrary(System.java:1122)
	at org.rosuda.JRI.Rengine.<clinit>(Rengine.java:19)
	at example.MyTest(MyTest.java:11)
```

設定していてもdllの依存がおかしいと怒られます。
jri.dllはbin/i386かbin/x86配下のdllに依存しているので、こちらも忘れず設定しましょう。


# まとめ

* RをJavaから動かすためのJRIってやつがある
* dllの設定で地味にハマるので、初見殺し。