I have been playing with rJava package, but since it seems that rJava is not aware of Java generic types, I have difficulties creating java object with generic type parameters. If I have a java class like:
public class A<T> {
private B<T> b;
public A(B<T> b) {
this.b = b;
}
}
I would like to create an A object from R session using .jnew()
by passing a B object already created (with instantiated type parameter), but rJava always gives error:
java.lang.NoSuchMethodError: <init>
Is there any work around for this?
There are a lot of moving parts in this question. Digging through the documentation for the various parts, I think that you need to do this on the line that broke:
gesinstance = .jnew("edu/cmu/tetrad/search/Ges", .jcast(dataset, "edu/cmu/tetrad/data/DataSet"))
The key difference being the call to .jcast
on the second argument. (I don't have R installed, so I could not test this - If it doesn't work, I will update my answer based on any feedback you can provide on new error messages.)
So then the question is "why that?" The answer seems to be:
DataReader.parseTabularData
returns an object with type DataSet
as you noted, but DataSet
is an interface not a class. That necessarily means that the actual object returned is of some class that implements the DataSet
interface.DataSet
. See the documentation for .jnew
(https://www.rforge.net/doc/packages/rJava/html/jnew.html), especially for the arguments that they denote by "...". This refers you to the corresponding part of the documentation for .jcall
(https://www.rforge.net/doc/packages/rJava/html/jcall.html), when then explains the requirement to call .jcast
(https://www.rforge.net/doc/packages/rJava/html/jcast.html) with some examples.The error that you got java.lang.NoSuchMethodError: <init>
was telling you that the JVM could not find the constructor that you called. This was mysterious looking in the example that you posted in the comments. (It might be good to edit your question, by the way, and include that information up there for posterity.) The code certainly looks right, and, knowing Java, I intuitively expected the interface to respect the polymorphism of the Java. Given that (for whatever reason), the interface to R does "exact" type matching without considering inheritance, it's clear that it will not find a constructor due to reason #1 above.
Finally, I didn't actually encounter any Java classes using generics in my limited exploration of Tetrad. As it turns out, that was a complete red herring though. Should it be an issue in the future, you'll probably want to check out "Type Erasure" (https://docs.oracle.com/javase/tutorial/java/generics/erasure.html). If you were interfacing between Java and C, C++, Fortran, any language that Java considers "native," then you'd deal with the generics in the native code by dealing in the type-erased forms. The rJava interface may be different though, since this seems to fall into the same general type of structure that tripped you up on your current problem. (Maybe worthy of its own bounty later!)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With