Search code examples
rrjava

rJava: pass 2 dimensional string array as function input


In my java class I write 3 test functions as follows:

public void try2dStringArray(String[][] arr) {
    System.out.println(arr.length);

}
public void try1dStringArray(String[] arr) {
    System.out.println(arr.length);

}
public void try2dDoubleArray(double[][] arr) {
    System.out.println(arr.length);

}

In R part I run the following:

library(rJava)
.jinit('/path/to/my/jar/app.jar')
obj <- .jnew('somepackage.Someclass')
doubleMatrix <- rbind(c(1,2), c(3,4))
stringMatrix <- rbind(c('a', 'b'), c('c', 'd'))
stringArray <- c('a', 'b')

result <- .jcall(obj,"V","try1dStringArray",
                 .jarray(stringArray, dispatch = T))
result <- .jcall(obj,"V","try2dDoubleArray",
                 .jarray(doubleMatrix, dispatch = T))
result <- .jcall(obj,"V","try2dStringArray",
                 .jarray(stringMatrix, dispatch = T))

Only the last one errors out:

Error in .jcall(obj, "V", "try2dStringArray", .jarray(stringMatrix, dispatch = T)) : 
  method try2dStringArray with signature ([[Ljava.lang.String;)V not found

How is String[][] different from double[][] in this case and how can I fix it?


Solution

  • At first, I thought that .jarray wasn't able to properly create a String[][] java array from a character R matrix. I was wrong and the error received when the code in the OP is run testifies it:

    .jcall(obj,"V","try2dStringArray",.jarray(stringMatrix, dispatch = T))
    #Error in .jcall(obj, "V", "try2dStringArray", .jarray(stringMatrix, dispatch = T)) : 
    #method try2dStringArray with signature ([[Ljava.lang.String;)V not found
    

    As can be seen, the signature (([[Ljava.lang.String;)V) seems correct (the double [[ should say that we actually passed a String[][] object), but for some reason .jcall can't find it.

    However, in rJava methods can be called also with the syntax obj$method(arg1,arg2,...), and in this way the method try2dStringArray is correctly called:

    obj$try2dStringArray(.jarray(stringMatrix, dispatch = T))
    #2