Search code examples
rrjava

Multidimensional arrays and rJava


I'm trying to call java code from R using the rJava package.

I need to pass a multidimensional (2d) doubles array to the java method and get back a 1d array of ints.

Here's the package information:

> sessionInfo()
R version 3.2.1 (2015-06-18)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 8 x64 (build 9200)

locale:
[1] LC_COLLATE=Portuguese_Brazil.1252  LC_CTYPE=Portuguese_Brazil.1252    LC_MONETARY=Portuguese_Brazil.1252
[4] LC_NUMERIC=C                       LC_TIME=Portuguese_Brazil.1252    

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] rJava_0.9-6         RevoUtilsMath_3.2.1

loaded via a namespace (and not attached):
[1] tools_3.2.1

This is the code

Sys.setenv(JAVA_HOME="") # have to do this for rJava...

require(rJava)

.jinit()
.jaddClassPath("C:/Users/Cássio/Dropbox/workspace/snncluster/target/snncluster-0.0.1-SNAPSHOT-jar-with-dependencies.jar")

set.seed(1234)

Y1 = matrix(rnorm(30*2, mean = 0, sd = 1), 30, 2)
Y2 = matrix(rnorm(30*2, mean = 10, sd = 1), 30, 2)

Y3 = rbind(Y1, Y2)

#snn = .jnew("br/fapesp/snn/snncluster/SNN")

snn = J("br.fapesp.snn.snncluster.SNN")

#lbls = .jcall(snn, "[I", "snn", .jarray(Y3,'[[D'), 10, 5, 7, evalArray = TRUE)

lbls = snn$snn(.jarray(Y3, '[[D'), as.integer(10), as.double(5), as.integer(7))

I can't seem to determine the correct way to call the method.

jmethod returns:

> .jmethods(snn)
 [1] "public static int br.fapesp.snn.snncluster.SNN.countIntersect(java.util.HashSet,java.util.HashSet)"
 [2] "public static int[] br.fapesp.snn.snncluster.SNN.snn(double[][],int,double,int)"                   
 [3] "public final void java.lang.Object.wait() throws java.lang.InterruptedException"                   
 [4] "public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException"           
 [5] "public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException"        
 [6] "public boolean java.lang.Object.equals(java.lang.Object)"                                          
 [7] "public java.lang.String java.lang.Object.toString()"                                               
 [8] "public native int java.lang.Object.hashCode()"                                                     
 [9] "public final native java.lang.Class java.lang.Object.getClass()"                                   
[10] "public final native void java.lang.Object.notify()"                                                
[11] "public final native void java.lang.Object.notifyAll()"          

I want to call the static method [2].

The return I get:

Error in .jcall("RJavaTools", "Ljava/lang/Object;", "invokeMethod", cl,  : 
  java.lang.NoSuchMethodException: No suitable method for the given parameters

Any idea what is the correct way to call the method?

Thanks.


Solution

  • The correct (working) way would be

    lbls = snn$snn(.jarray(Y3, dispatch = TRUE), as.integer(10), as.double(5), as.integer(7))
    

    Thanks to S. Urbanek for the pointer.