使用rJava

时间:2015-08-17 14:42:48

标签: java r rjava jackcess

我对Java不是很熟悉,但我尝试在R(我的收藏)中完成这项任务!

这个Java库名为Jackcess。我想连接到此库并在其中打开MS Access 2003 .mdb文件。 Jackcess cookbook告诉我使用此库的第一步是:

Database db = DatabaseBuilder.open(new File("mydb.mdb"));

或@Gord建议,

File file = new File("C:/Users/Public/jackcessTest.mdb");
DatabaseBuilder dbbo = new DatabaseBuilder();
dbbo.setFile(file);
Database db = dbbo.open();

但是我在这第一步就陷入困境。

我已经安装了Java和rJava并设置了有关目录的所有内容。 这是我在R

中的代码
library(rJava)

.jinit()
.jaddClassPath("java/jackcess-2.1.2.jar") # there I have put the downloaded jar file of Jackcess

# .jaddClassPath("java/commons-logging-1.2.jar") # this is the commons-logging class that Jackcess depends on, commented to replicate problem 2] in my question.



file.name <- "D:/63.mdb" # some data base .mdb file (containing only tables)

file <- .jnew("java/io/File",file.name)
dbbo <- .jnew("com/healthmarketscience/jackcess/DatabaseBuilder")

[编辑:我发现我有两个问题,一个解决了,一个还没有。] 到目前为止,一切都还可以,但从现在开始我遇到了一些问题:

1]正确地从Jackcess调用一个没有签名不匹配的方法,这些都不起作用:

dbbo <- .jcall(dbbo,"L<DatabaseBuilder>","setFile",file)
dbbo <- .jcall(dbbo,"Lcom/healthmarketscience/jackcess/DatabaseBuilder","setFile",file)

我收到此错误:

Error in .jcall(dbbo, "Lcom/healthmarketscience/jackcess/DatabaseBuilder",  : 
method setFile with signature (Ljava/io/File;)Lcom/healthmarketscience/jackcess/DatabaseBuilder not found

我找到了这一步的答案,我只需要在类定义字符串末尾加一个分号(;)。

dbbo <- .jcall(dbbo,"Lcom/healthmarketscience/jackcess/DatabaseBuilder;","setFile",file)

2]正确调用open方法,我的第一轮尝试:

 db <- .jcall(dbbo,"Lcom/healthmarketscience/jackcess/Database;","open",evalArray = FALSE,evalString = FALSE)

我收到此错误:

 Error in .jcall(dbbo, "Lcom/healthmarketscience/jackcess/Database;", "open",  : 
 java.lang.NoClassDefFoundError: org/apache/commons/logging/LogFactory

我用Google搜索并发现Jackcess依赖于一些名为commons-logging的库,因此下载并将其添加到classpath解决了这个问题

3]正确调用open方法,我的第二轮尝试:在类路径中使用commons-logging

db <- .jcall(dbbo,"Lcom/healthmarketscience/jackcess/Database;","open",evalArray = FALSE,evalString = FALSE)

这给了我这个错误:

Error in .jcall(dbbo, "Lcom/healthmarketscience/jackcess/Database;", "open",  : 
java.lang.NoClassDefFoundError: Could not initialize class com.healthmarketscience.jackcess.impl.DatabaseImpl

对此错误的任何想法?

[注意]:在编辑之前已经提出了一些答案,所以现在看起来似乎无关紧要,但我已经按照上面解释的步骤使用了它们。

2 个答案:

答案 0 :(得分:0)

以下代码使用&#34; real&#34;的.setFile.open方法在Java中显示了另一种方法。 DatabaseBuilder对象:

File file = new File("C:/Users/Public/jackcessTest.mdb");
DatabaseBuilder dbbo = new DatabaseBuilder();
dbbo.setFile(file);
Database db = dbbo.open();

在rJava中尝试类似的东西,看看它是否适合你。

修改:更新问题

您提到您已将Apache commons-logging添加到CLASSPATH中,但Jackcess还依赖于Apache commons-lang v2.x( not v3.x),因此请尝试下载并将其包含在您的CLASSPATH中。

答案 1 :(得分:0)

3条建议:

在classPath中包含commons-lang-2.0.jar,类似于

rJava::.jaddClassPath("commons-lang-2.0.jar")

简单的方法是尝试使用J()调用:

dbb <- rJava::.jnew("com/healthmarketscience/jackcess/DatabaseBuilder")
dbjfile <- rJava::.jnew('java/io/File', "D:/63.mdb")
dbop <- rJava::J(dbb, "open", dbjfile)

对于它的价值,如果你真的想以低级方式去做,这是尝试的一种方式:

dbop <- .jcall(
    "RJavaTools"
  , "Ljava/lang/Object;"
  , "invokeMethod"
  , .jcall(dbb, "Ljava/lang/Class;", "getClass")
  , .jcast(dbb, "java/lang/Object")
  , .jnew("java/lang/String", "open")
  , .jarray(list(dbjfile), "java/lang/Object", dispatch = FALSE)
  , .jarray(rJava:::._java_class_list(list(dbjfile)), "java/lang/Class", dispatch = FALSE)
  , use.true.class = TRUE
  , evalString = TRUE
  , evalArray = FALSE
  )