はじめに
半年ほど前に新人さんから「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.
要は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使いはこちら。
// https://mvnrepository.com/artifact/org.nuiton.thirdparty/JRI
compile group: 'org.nuiton.thirdparty', name: 'JRI', version: '0.9-6'
Maven使いはこちら。
<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を通してやらないとダメ。
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
下の設定は無くても動きました。
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引数
-Djava.library.path="C:\Program Files\R\R-3.3.1\library\rJava\jri\i386"
を追加
よく発生するエラー
jri.dllのパスを通すのを忘れる
よくこんなエラーになる。
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のパスに変数を通していないと怒られる
上記を突破すると下記が出て来る。
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の設定で地味にハマるので、初見殺し。