.jcall calls a Java method with the supplied arguments.

.jcall(obj, returnSig = "V", method, ..., evalArray = TRUE,
    evalString = TRUE, check = TRUE, interface = "RcallMethod",
    simplify = FALSE, use.true.class = FALSE)

Arguments

obj

Java object (jobjRef as returned by .jcall or .jnew) or fully qualified class name in JNI notation (e.g. "java/lang/String").

returnSig

Return signature in JNI notation (e.g. "V" for void, "[I" for int[] etc.). For convenience additional type "S" is supported and expanded to "Ljava/lang/String;", re-mapping "T" to represent the type short.

method

The name of the method to be called

...

Any parameters that will be passed to the Java method. The parameter types are determined automatically and/or taken from the jobjRef object. All named parameters are discarded.

evalArray

This flag determines whether the array return value is evaluated (TRUE) or passed back as Java object reference (FALSE).

simplify

If evalArray is TRUE then this argument is passed to .jevalArray().

evalString

This flag determines whether string result is returned as characters or as Java object reference.

check

If set to TRUE then checks for exceptions are performed before and after the call using .jcheck(silent=FALSE). This is usually the desired behavior, because all calls fail until an exception is cleared.

interface

This option is experimental and specifies the interface used for calling the Java method; the current implementation supports two interfaces:

"RcallMethod"

the default interface.

"RcallSyncMethod"

synchronized call of a method. This has similar effect as using synchronize in Java.

use.true.class

logical. If set to TRUE, the true class of the returned object will be used instead of the declared signature. TRUE allows for example to grab the actual class of an object when the return type is an interface, or allows to grab an array when the declared type is Object and the returned object is an array. Use FALSE for efficiency when you are sure about the return type.

Value

Returns the result of the method.

Details

.jcall requires exact match of argument and return types. For higher efficiency .jcall doesn't perform any lookup in the reflection tables. This means that passing subclasses of the classes present in the method definition requires explicit casting using .jcast. Passing null arguments also needs a proper class specification with .jnull.

Java types long and float have no corresponding types in R and therefore any such parameters must be flagged as such using .jfloat and .jlong functions respectively.

Java also distinguishes scalar and array types whereas R doesn't have the concept of a scalar. In R a scalar is basically a vector (called array in Java-speak) of the length 1. Therefore passing vectors of the length 1 is ambiguous. .jcall assumes that any vector of the length 1 that corresponds to a native Java type is a scalar. All other vectors are passed as arrays. Therefore it is important to use .jarray if an arbitrary vector (including those of the length 1) is to be passed as an array parameter.

Important note about encoding of character vectors: Java interface always works with strings in UTF-8 encoding, therefore the safest way is to run R in a UTF-8 locale. If that is not possible for some reason, rJava can be used in non-UTF-8 locales, but care must be taken. Since R 2.7.0 it is possible to associate encoding with strings and rJava will flag all strings it produces with the appropriate UTF-8 tag. R will then perform corresponding appropriate conversions where possible (at a cost of speed and memory usage), but 3rd party code may not (e.g. older packages). Also rJava relies on correct encoding flags for strings passed to it and will attempt to perform conversions where necessary. If some 3rd party code produces strings incorrectly flagged, all bets are off.

Finally, for performance reasons class, method and field names as well as signatures are not always converted and should not contain non-ASCII characters.

See also

Examples

.jcall("java/lang/System","S","getProperty","os.name")
#> [1] "Linux"
if (!nzchar(Sys.getenv("NOAWT"))) {
  f <- .jnew("java/awt/Frame","Hello")
  .jcall(f,,"setVisible",TRUE)
}