rJava - .jcall calling issue: method with signature not found - r

I am trying to call a method in java class with rJava for a few days and I did not yet figure it out what I am doing wrong. Maybe someone here will have a some clues for me.
The situation looks like this:
I load library and initializing an object (that's works fine):
library(rJava)
.jinit('C:/javatemp/worker.jar')
jobject <- .jnew("worker.concrete")
I list methods and I get fine result:
.jmethods(jobject)
> [1] "public java.util.List worker.concrete.lookup(java.lang.CharSequence)"
I am preparing input structure which also works fine:
word <- .jnew("java/lang/String", "a word")
input = .jcast(word, "java/lang/CharSequence", check = TRUE)
However when I am trying to execute the method I get an error that such method does not exist...
out = .jcall(jobject,"Ljava/util/List","lookup",input)
> Error in .jcall(jobject, "Ljava/util/List", "lookup", input) :
method lookup with signature (Ljava/lang/CharSequence;)Ljava/util/List not found
Does anyone have an idea how to call such method?

Sorry for answering an old question, but this has bugged me as well for some time. The answer is: ;
The format of type specification for non-primitive return types is Lpackage/subpackage/Type; - it has to end with a semicolon. So in the example above, you would need:
out = .jcall(jobject,"Ljava/util/List;","lookup",input)

Related

Detect methods in other environments in R -- for testing in testthat

Is it possible to allow "UseMethod" to see class functions defined in other environments? See the below code for an example. I would like the h.logical to be detected too such that h(TRUE) would return "logical".
h <- function(x) {
UseMethod("h")
}
h.character <- function(x){ "char"}
h.numeric <- function(x) { "num" }
aa = list(h.logical=function(x){"logical"})
attach(aa)
h("a")
h(10)
h(TRUE)
This code now throws an error in the last line:
Error in UseMethod("h") : no applicable method for 'h' applied to an object of class "logical"
Solving the issue with this example suffices. If that is not possible, I would appreciate help solving the actual use case in another way.
The use case is as follows: I have a package with functions like h above, then I want to add a class to that function. This works fine just adding the new function to .Globalenv. The problem occurs when I want to test this using testthat as I am not allowed to write to .Globalenv within a test. Adding the new class function to some other environment within the test makes it detectable by methods(), however, UseMethod still does not see it and throws an error. Any ideas?
Can I use something else then UseMethod for this purpose or do some other hack while testing to mimic the actual usage?
Any help or pointers to how to handle this is highly appreciated!

SSOAP processWSDL SoapType

I'm new to R/web services.
I'm trying to use R's SSOAP package to get/post soap messages.
I want to generate functions definitions using the genSOAPCLientInterface by way of the processWSDL function.
when i run the processWSDL function, i get the following error message, which i dont know how to interpret:
Error in SOAPType(el, namespaceDefs=namespaceDefinitions):could not find function "SOAPType"
any help/pointers would be very helpful.
wsdl_doc<-xmlParse(paste0(wsdl_url, '?wsdl')
definitions<-processWSDL(wsdl_doc, verbose=T, useInternalNodes=T)
Error in SOAPType(el, namespaceDefs = namespaceDefinitions) :
could not find function "SOAPType"
SOAPType is a class used in SSOAP package, but it is declared in package XMLSchema. And for some reason it is not an exported class.
This workaround helped me to make the function processWSDL() working for me:
SOAPType = XMLSchema:::SOAPType
def <- processWSDL(doc)

R 'object XX not found' error thrown inside function, but not in script

I am fairly new to R, so my apologies if this question is a bit silly.
I am calling a function in an external package ('mmlcr', although I don't think that is directly relevant to my problem), and one of the required inputs (data) is a data.frame. I compose the data.frame from various data using the following approach (simplified for illustration):
#id, Time, and value are vectors created elsewhere in the code.
myData = data.frame(a=id, b=Time, c=value)
out <- mmlcr( input1, input2, data=myData, input4)
Which throws the error:
Error in is.data.frame(data) : object 'myData' not found
The debugger indicates that this error is thrown during the mmlcr() call.
I then added a print(ls()) immediately prior to the mmlcr() call, and the output confirmed that "myData" was in my function workspace; further is.data.frame(myData) returned TRUE. So it seems that "myData" is successfully being created, but for some reason it is not passing into the mmlcr() function properly. (Commenting this line causes no error to be thrown, so I'm pretty sure this is the problematic line).
However, when I put the exact same code in a script (i.e., not within a function block), no such error is thrown and the output is as expected. Thus, I assume there is some scoping issue that arises.
I have tried both assignment approaches:
myData = data.frame(a=id, b=Time, c=value)
myData <- data.frame(a=id, b=Time, c=value)
and both give me the same error. I admit that I don't fully understand the scope model in R (I've read about the differences between = and <- and I think I get it, but I'm not sure).
Any advice you can offer would be appreciated.
MMLCR is now deprecated and you should search for some alternatives. Without looking too much into it, I sleuthed through an old repo and found the culprit:
m <- eval(m, data)
in the function mmlcr.default. There are a lot of reasons why this is bad, but scoping is the big one. R has this issue with the subset.data.frame function, see my old SO question. Rather than modify the source code, I would find a way to do your function with a subroutine using a for, repeat, or while loop.

tryCatch does not catch an error if called though RScript

I'm facing a strange issue in R.
Consider the following code (a really simplified version of the real code but still having the problem) :
library(timeSeries)
tryCatch(
{
specificWeekDay <- 2
currTs <- timeSeries(c(1,2),c('2012-01-01','2012-01-02'),
format='%Y-%m-%d',units='A')
# just 2 dates out of range
start <- time(currTs)[2]+100*24*3600
end <- time(currTs)[2]+110*24*3600
# this line returns an empty timeSeries
currTs <- window(currTs,start=start,end=end)
message("Up to now, everything is OK")
# this is the line with the uncatchable error
currTs[!(as.POSIXlt(time(currTs))$wday %in% specificWeekDay),] <- NA
message("I'm after the bugged line !")
},error=function(e){message(e)})
message("End")
When I run that code in RGui, I correctly get the following output:
Up to now, everything is OK
error in evaluating the argument 'i' in
selecting a method for function '[<-': Error in
as.POSIXlt.numeric(time(currTs)) : 'origin' must be supplied
End
Instead, when I run it through RScript (in windows) using the following line:
RScript.exe --vanilla "myscript.R"
I get this output:
Up to now, everything is OK
Execution interrupted
It seems like RScript crashes...
Any idea about the reason?
Is this a timeSeries package bug, or I'm doing something wrong ?
If the latter, what's the right way to be sure to catch all the errors ?
Thanks in advance.
EDIT :
Here's a smaller example reproducing the issue that doesn't use timeSeries package. To test it, just run it as described above:
library(methods)
# define a generic function
setGeneric("foo",
function(x, ...){standardGeneric("foo")})
# set a method for the generic function
setMethod("foo", signature("character"),
function(x) {x})
tryCatch(
{
foo("abc")
foo(notExisting)
},error=function(e)print(e))
It seems something related to generic method dispatching; when an argument of a method causes an error, the dispatcher cannot find the signature of the method and conseguently raises an exception that tryCatch function seems unable to handle when run through RScript.
Strangely, it doesn't happen for example with print(notExisting); in that case the exception is correctly handled.
Any idea about the reason and how to catch this kind of errors ?
Note:
I'm using R-2.14.2 on Windows 7
The issue is in the way the internal C code implementing S4 method dispatch tries to catch and handle some errors and how the non-interactive case is treated in this approach. A work-around should be in place in R-devel and R-patched soon.
Work-around now committed to R-devel and R-patched.
Information about tryCatch() [that the OP already knew and used but I didn't notice]
I think you are missing that your tryCatch() is not doing anything special with the error, hence you are raising an error in the normal fashion. In interactive use the error is thrown and handled in the usual fashion, but an error inside a script run in a non-interactive session (a la Rscript) will abort the running script.
tryCatch() is a complex function that allows the potential to trap and handle all sorts of events in R, not just errors. However by default it is set up to mimic the standard R error handling procedure; basically allow the error to be thrown and reported by R. If you want R to do anything other than the basic behaviour then you need to add a specific handler for the error:
> e <- simpleError("test error")
> tryCatch(foo, error = function(e) e,
+ finally = writeLines("There was a problem!"))
There was a problem!
<simpleError in doTryCatch(return(expr), name, parentenv, handler): object 'foo'
not found>
I suggest you read ?tryCatch in more detail to understand better what it does.
An alternative is to use try(). To modify your script I would just do:
# this is the line with the uncatchable error
tried <- try(currTs[!(as.POSIXlt(time(currTs))$wday %in% specificWeekDay),] <- NA,
silent = TRUE)
if(inherits(tried, "try-error")) {
writeLines("There was an error!")
} else {
writeLines("Everything worked fine!")
}
The key bit is to save the object returned from try() so you can test the class, and to have try() operate silently. Consider the difference:
> bar <- try(foo)
Error in try(foo) : object 'foo' not found
> bar <- try(foo, silent = TRUE)
> class(bar)
[1] "try-error"
Note that in the first call above, the error is caught and reported as a message. In the second, it is not reported. In both cases an object of class "try-error" is returned.
Internally, try() is written as a single call to tryCatch() which sets up a custom function for the error handler which reports the error as a message and sets up the returned object. You might wish to study the R code for try() as another example of using tryCatch().

How to work with an expected return type of "java.lang.Class"?

I thought I'd try to write an R interface to Scribe (mature OAuth library for Java by Pablo Fernandez) as a way of refreshing myself on Java (not used it in 8 years), learning rJava and to make better use of the Twitter API. But mostly because it's Friday afternoon and I thought it'd be fun. :)
Unfortunately I haven't got very far...
I downloaded the .jar file for scribe and also commons-condec (its only dependency, which I subsequently unzipped). I've ran the code in Java using netbeans and it works fine using his twitter example.
I was OK for the first few lines of code by just following the rJava documenation:
# load R packages
library(rJava)
# Initialise
.jinit()
# Add class paths
d1 <- "C:/Users/Tony/Documents/R/java/scribe-1.1.0.jar"
d2 <- "C:/Users/Tony/Documents/R/java/commons-codec-1.4/"
.jaddClassPath(path=c(d1, d2))
But then scribe quick start guide says the following is needed:
// Java Code
OAuthService service = new ServiceBuilder()
.provider(TwitterApi.class)
.apiKey("6icbcAXyZx67r8uTAUM5Qw")
.apiSecret("SCCAdUUc6LXxiazxH3N0QfpNUvlUy84mZ2XZKiv39s")
.build();
I can't figure out how to rewrite that into rJava parlance. A little web searching suggests I should do it in parts, so first I did:
# Create object (back to R code again)
( service <- .jnew("org.scribe.builder.ServiceBuilder") )
[1] "Java-Object{org.scribe.builder.ServiceBuilder#58fe64b9}"
# Set up apiKey and apiSecret using "$" shortcut
service$apiKey("6icbcAXyZx67r8uTAUM5Qw")
service$apiSecret("SCCAdUUc6LXxiazxH3N0QfpNUvlUy84mZ2XZKiv39s")
Good so far. Then I need to figure out what return type is expected from the provider function:
# Inspect return type
.jmethods(service, "provider")
[1] "public org.scribe.builder.ServiceBuilder org.scribe.builder.ServiceBuilder.provider(java.lang.Class)"
It needs "java.lang.Class". This is where I get confused. What does that mean? I guess, looking at the source, it needs a return type of type "ServiceBuilder", but how to do that? This was my best guess after looking at ?.jcall (note: 'use.true.class = TRUE' didn't do anything):
> .jcall(obj = service, returnSig = "Lorg.scribe.builder.ServiceBuilder;", method = "org.scribe.builder.ServiceBuilder.provider", "org.scribe.builder.api.TwitterApi")
Error in .jcall(obj = service, returnSig = "Lorg.scribe.builder.ServiceBuilder;", :
method org.scribe.builder.ServiceBuilder.provider with signature (Ljava/lang/String;)Lorg.scribe.builder.ServiceBuilder; not found
Any ideas?
It looks to me like the provider method returns ServiceBuilder and takes a Class as a parameter.
In Java if you put the classname followed by .class that makes a class literal object in the code. If you instead load the class using reflection you can refer to a class by its string name. I'm not sure how this works in R but in Java the syntax is:
Class c = Class.forName("org.scribe.builder.api.TwitterApi");
This puts the class instance into the variable c. Then you could call the provider method:
service$provider(c);

Resources