2016年11月21日 星期一

[R] R 上安裝 RJDBC 和 rJava 的除錯



話說早前有關R找到本不錯的教學書,試過模仿它測試股票投資策略的那一章後,正要嘗試 R與MySQL的連接,但想從書中的RODBC Library改為用RJDBC Library。當時已經安裝好MySQL,MySQL Workbench,下載了JDBC Connector 的 jar 檔,在 R 上安裝了 RJDBC Library,但要使用時卻一直在報錯而用不到。在印度的最後幾天,想起再繼續 R 的項目,跟 rJava 的設定糾纏了幾小時,在最氣餒的時候終於有了突破,一步步順利的通關。

原本報錯的情況,是在載入 library(RJDBC) 的時候,回報說在調用 library(rJava) 的 .jinit() 時出錯,找不到要用的JVM。
R> .jinit()
JavaVM: requested Java version ((null)) not available. Using Java at "" instead.
JavaVM: Failed to load JVM: /bundle/Libraries/libserver.dylib
JavaVM FATAL: Failed to load the jvm library.
Error in .jinit() : JNI_GetCreatedJavaVMs returned -1

之後己經事前準備好的:
1. R 和 Java 是本身己經在用的,本身分別搭配著 R Studio 和 Eclipse 使用

2. 安裝好MySQL 和 MySQL Workbench。記住連接用的user和pwd
下載:http://dev.mysql.com/downloads/mysql/http://dev.mysql.com/downloads/workbench/

3. 下載JDBC Connector 的jar檔:
下載:http://dev.mysql.com/downloads/connector/j/

開始

這個幾月多了學習Java,才接觸多了JAVA的環境變數,在網上找了試了很久,跟著電腦/Java/R 的版本不同還有不同做法。看過有些說:Java 64bit的話,R也要裝64bit的;EI Captain echo $JAVA_HOME時回看到空的,但這個在我的電腦中應該設定成"/Library/Java/JavaVirtualMachines/jdk1.8.0_73.jdk/Contents/Home"。在執行 ~$ export JAVA_HOME=$(/usr/libexec/java_home) 之後就可以指向正確位置。

當中 "/usr/libexec/java_home" 是一個Symbolic link 指向 "/System/Library/Frameworks/JavaVM.framework/Versions/Current/Commands/java_home"。而大家傳回的內容為: "/Library/Java/JavaVirtualMachines/jdk1.8.0_73.jdk/Contents/Home"。在執行這句之後,就可以把"/Library/Java/JavaVirtualMachines/jdk1.8.0_73.jdk/Contents/Home" 放到 $JAVA_HOME 內。
~$ export JAVA_HOME=$(/usr/libexec/java_home)

我用的是EI Captain;Java 1.8;R 3.3.1。 完成後設定如下:
~$ sw_vers
ProductName:    Mac OS X
ProductVersion:    10.11.3
BuildVersion:    15D21

~$ java -version
java version "1.8.0_73"
Java(TM) SE Runtime Environment (build 1.8.0_73-b02)
Java HotSpot(TM) 64-Bit Server VM (build 25.73-b02, mixed mode)

~$ R --version
R version 3.3.1 (2016-06-21) -- "Bug in Your Hair"
Copyright (C) 2016 The R Foundation for Statistical Computing
Platform: x86_64-apple-darwin13.4.0 (64-bit)

~$ ls /Library/Java/JavaVirtualMachines/
jdk1.8.0_73.jdk

~$ which java
/usr/bin/java

~$ /usr/libexec/java_home
/Library/Java/JavaVirtualMachines/jdk1.8.0_73.jdk/Contents/Home

~$ echo $JAVA_HOME
/Library/Java/JavaVirtualMachines/jdk1.8.0_73.jdk/Contents/Home
以上是很多嘗試後的結果,希望沒有遺漏什麼吧,不過這還未夠。在各種嘗試之後。。。

有一個有用的方法是看到說這2句可以解決問題(http://conjugateprior.org/2014/12/r-java8-osx/),所以就一輪改動後再加上了這些步驟:
~$ sudo R CMD javareconf

R> install.packages('rJava',"source")


不過我的畫面沒有自動彈出Mirror的選項,所以找出指定平時會用的source, 改為自行指定:
R> install.packages('rJava', repos='http://cran.us.r-project.org')

R 就開始下載和安裝Package。然後是在安裝階段出錯的,今次說找不到javac。回到Terminal查看和修改JAVA_HOME(曾經誤用: $JAVA_HOME = /Library/Java/JavaVirtualMachines/jdk1.8.0_73.jdk/Contents/Home/jre)
~$ echo $JAVA_HOME
~$ export JAVA_HOME=$(/usr/libexec/java_home)

安裝成功後,輪到在載入時出錯:
R> library("rJava")
Error : .onLoad failed in loadNamespace() for 'rJava', details:
  call: dyn.load(file, DLLpath = DLLpath, ...)
  error: unable to load shared object '/Library/Frameworks/R.framework/Versions/3.3/Resources/library/rJava/libs/rJava.so':

在Terminal上建立symbolic linked to libjvm.dylib 的連結檔放入/usr/local/lib,如果產生的連結檔已存在,則先刪除現有的連結檔:
~$ sudo ln -f -s $(/usr/libexec/java_home)/jre/lib/server/libjvm.dylib /usr/local/lib

最後再重新安裝和載入Library(rJava)。嘗試執行 .jinit(),終於成功了⋯⋯

測試

成功安裝後可以跟著 https://rforge.net/rJava/ 中的步驟嘗試。
R> library(rJava)
R> .jinit() # 啟動JVM
R> s <- .jnew("java/lang/String", "Hello World!") # 建立一個String物件
R> .jcall(s,"I","length") # 呼叫String的length方法[1] 12
R> print(s) # s 是一個Java Object
[1] "Java-Object: Hello World"
R> .jstrVal(s) # 傳回 s 的 String 內容[1] "Hello World"

還有接下來的RJDBC:https://www.rforge.net/RJDBC/
R> library(RJDBC)
R> drv <- JDBC(driverClass="com.mysql.jdbc.Driver",
      classPath="(Location)/mysql-connector-java-5.1.39-bin.jar", "`")
R> conn <- dbConnect(drv, "jdbc:mysql://localhost:3306/sakila", (User), (Password))
R> dbListTables(conn)
R> data()
R> dbWriteTable(conn, "iris", iris)

沒有留言:

張貼留言