Adrian Dragulescu
2008-Nov-06 15:04 UTC
[Rd] problem packaging S4 class that contains a slot of jobjRef class
Hello, I'm trying to package some source files that link R to a broker using a Java API and the rJava package. I am successful doing the connection and operate on it using my R code. I would like to package the files and release the package. I created some S4 classes to hold several Java objects. I use WinXP and R 2.7.1. I've searched RSeek and the Wiki for help, but could not find a solution. Here is my class definition: twsConnect <- function(...) new("twsConnect", ...) setClass( Class="twsConnect", representation=representation( clientId = "integer", host = "character", port = "integer", reference = "jobjRef"), prototype=prototype( clientId = as.integer(0), host = "", port = as.integer(7496), reference = .jnull()) ) setMethod("initialize", "twsConnect", function( .Object, clientId = 0, host = "", port = 7496, ...) { # hook up to the TWS ref <- .jnew("dev/AAD_Trader", as.integer(clientId), host, as.integer(port)) if (class(ref)[1] != "jobjRef") stop("Could not connect. Check your settings.") .Object at clientId <- as.integer(clientId) .Object at host <- as.character(host) .Object at port <- as.integer(port) .Object at reference <- ref .Object } ) setMethod("show", "twsConnect", function(object){ cat("Object of class \"", class(object), "\":\n", sep="") lines <- NULL for (s in slotNames(object)){ cont <- slot(object, s) if (is.character(cont))cont <- paste('"', cont, '"', sep="") if (class(cont)=="jobjRef") cont <- "jobjRef" lines <- paste(lines, paste(s, " = ", cont, "\n", sep=""), sep="") } cat(lines) } ) I have other files too. Here is the output from package creation: S:\All\Risk\Software\R\R-2.7.1\bin>Rcmd build --force --binary H:/user/R/Adrian/RIB/ * checking for file 'H:/user/R/Adrian/RIB/DESCRIPTION' ... OK * preparing 'H:/user/R/Adrian/RIB': * checking DESCRIPTION meta-information ... OK * removing junk files * excluding invalid files from 'RIB' Subdirectory 'R' contains invalid file names: .make.IB.package.R .utilities.R * checking for LF line-endings in source and make files * checking for empty or unneeded directories WARNING: directory 'RIB/inst/doc' is empty * building binary distribution WARNING: some HTML links may not be found installing R.css in C:/DOCUME~1/e47187/LOCALS~1/Temp/Rinst238480883 Using auto-selected zip options '' ---------- Making package RIB ------------ adding build stamp to DESCRIPTION installing NAMESPACE file and metadata installing R files installing inst files preparing package RIB for lazy loading Loading required package: rJava Warning: package 'rJava' was built under R version 2.7.2 Loading required package: zoo Attaching package: 'zoo' The following object(s) are masked from package:base : as.Date.numeric Creating a new generic function for "summary" in "RIB" installing man source files installing indices installing help >>> Building/Updating help pages for package 'RIB' Formats: text html latex example chm IBrokers-package text html latex example chm reqAccountUpdates text html latex example chm reqHistoricalData text html latex example chm twsConnect text html latex example chm Note: removing empty section \details Note: removing empty section \details twsContract text html latex example chm twsOrder text html latex example chm hhc: not found CHM compile failed: HTML Help Workshop not installed? adding MD5 sums packaged installation of package 'RIB' as RIB_0.1.0.zip * DONE (RIB) Not clean yet, but good for testing. So, from R:> require("RIB")Loading required package: RIB Loading required package: rJava Loading required package: zoo Attaching package: 'zoo' The following object(s) are masked from package:base : as.Date.numeric Warning message: package 'rJava' was built under R version 2.7.2> tws <- twsConnect() > twsObject of class "twsConnect": clientId = 0 host = "" port = 7496 reference = jobjRef> tws at reference[1] "Java-Object<null>" So I have no connection...> tws <- new("twsConnect", 1, "", 7496)Error in initialize(value, ...) : cannot use object of class "numeric" in new(): class "twsConnect" does not extend that class>but if I source the file:> source("H:/user/R/Adrian/RIB/R/twsConnect.R") > tws <- twsConnect() > twsObject of class "twsConnect": clientId = 0 host = "" port = 7496 reference = jobjRef> > tws at reference[1] "Java-Object{dev.AAD_Trader at 12558d6}">Things work as I want, I have the connection. What does source do, that I miss when packaging? My NAMESPACE file is: exportPattern("^[^\\.]") exportClasses("twsConnect", "twsContract", "twsExecutionFilter", "twsOrder") exportMethods("show") My .onLoad function contains ".jpackage(pkgname)". I tried to package just the class twsConnect without the slot reference, and things worked out fine. I tried to say that twsConnect contains "jobjRef" but did not have much success. Thanks a lot, Adrian Dragulescu
Simon Urbanek
2008-Nov-06 22:41 UTC
[Rd] problem packaging S4 class that contains a slot of jobjRef class
Adrian, my guess would be that you're trying to crate some Java objects at the top level of your package. That won't work, because R stores a serialized image of created objects for efficiency and hence the reference to any Java objects that you create will disappear as soon as you're done installing the package. When you try to load the package you'll end up with null references for all objects you have attempted to create that way. You have two options to avoid that: 1) create objects at load time - i.e. in the initialization function after you have called .jpackage. Only then is Java up and running so you can safely create Java objects 2) [not recommended] use .jcache to serialize objects you want to keep at the top level after creating them. They will be then lazily deserialized after the package has been loaded. However, this requires all such classes to implement Serializable interface on the Java side and is conceptually not clean, because you have to be careful when your cached serialization goes out of sync with the actual object (see details in the documentation of .jcache). This is just my guess based on the symptoms since I think you actually failed to send us the part of code that triggers the problem. Cheers, Simon On Nov 6, 2008, at 10:04 , Adrian Dragulescu wrote:> > > Hello, > > I'm trying to package some source files that link R to a broker using > a Java API and the rJava package. I am successful doing the > connection > and operate on it using my R code. I would like to package the > files and > release the package. > > I created some S4 classes to hold several Java objects. I use WinXP > and R > 2.7.1. I've searched RSeek and the Wiki for help, but could not > find a > solution. > > Here is my class definition: > twsConnect <- function(...) > new("twsConnect", ...) > > setClass( > Class="twsConnect", > representation=representation( > clientId = "integer", > host = "character", > port = "integer", > reference = "jobjRef"), > prototype=prototype( > clientId = as.integer(0), > host = "", > port = as.integer(7496), > reference = .jnull()) > ) > > setMethod("initialize", "twsConnect", function( > .Object, clientId = 0, host = "", port = 7496, ...) > { > # hook up to the TWS > ref <- .jnew("dev/AAD_Trader", as.integer(clientId), host, > as.integer(port)) > > if (class(ref)[1] != "jobjRef") > stop("Could not connect. Check your settings.") > > .Object at clientId <- as.integer(clientId) > .Object at host <- as.character(host) > .Object at port <- as.integer(port) > .Object at reference <- ref > > .Object > } > ) > > > setMethod("show", "twsConnect", > function(object){ > cat("Object of class \"", class(object), "\":\n", sep="") > lines <- NULL > for (s in slotNames(object)){ > cont <- slot(object, s) > if (is.character(cont))cont <- paste('"', cont, '"', sep="") > if (class(cont)=="jobjRef") cont <- "jobjRef" > lines <- paste(lines, paste(s, " = ", cont, "\n", > sep=""), sep="") > } > cat(lines) > } > ) > > > > I have other files too. Here is the output from package creation: > S:\All\Risk\Software\R\R-2.7.1\bin>Rcmd build --force --binary > H:/user/R/Adrian/RIB/ > * checking for file 'H:/user/R/Adrian/RIB/DESCRIPTION' ... OK > * preparing 'H:/user/R/Adrian/RIB': > * checking DESCRIPTION meta-information ... OK > * removing junk files > * excluding invalid files from 'RIB' > Subdirectory 'R' contains invalid file names: > .make.IB.package.R .utilities.R > * checking for LF line-endings in source and make files > * checking for empty or unneeded directories > WARNING: directory 'RIB/inst/doc' is empty > * building binary distribution > WARNING: some HTML links may not be found > installing R.css in C:/DOCUME~1/e47187/LOCALS~1/Temp/Rinst238480883 > > Using auto-selected zip options '' > > ---------- Making package RIB ------------ > adding build stamp to DESCRIPTION > installing NAMESPACE file and metadata > installing R files > installing inst files > preparing package RIB for lazy loading > Loading required package: rJava > Warning: package 'rJava' was built under R version 2.7.2 > Loading required package: zoo > > Attaching package: 'zoo' > > > The following object(s) are masked from package:base : > > as.Date.numeric > > Creating a new generic function for "summary" in "RIB" > installing man source files > installing indices > installing help >>>> Building/Updating help pages for package 'RIB' > Formats: text html latex example chm > IBrokers-package text html latex example chm > reqAccountUpdates text html latex example chm > reqHistoricalData text html latex example chm > twsConnect text html latex example chm > Note: removing empty section \details > Note: removing empty section \details > twsContract text html latex example chm > twsOrder text html latex example chm > hhc: not found > CHM compile failed: HTML Help Workshop not installed? > adding MD5 sums > > packaged installation of package 'RIB' as RIB_0.1.0.zip > * DONE (RIB) > > Not clean yet, but good for testing. > > So, from R: > >> require("RIB") > Loading required package: RIB > Loading required package: rJava > Loading required package: zoo > > Attaching package: 'zoo' > > > The following object(s) are masked from package:base : > > as.Date.numeric > > Warning message: > package 'rJava' was built under R version 2.7.2 >> tws <- twsConnect() >> tws > Object of class "twsConnect": > clientId = 0 > host = "" > port = 7496 > reference = jobjRef >> tws at reference > [1] "Java-Object<null>" > So I have no connection... > >> tws <- new("twsConnect", 1, "", 7496) > Error in initialize(value, ...) : > cannot use object of class "numeric" in new(): class "twsConnect" > does > not extend that class >> > > but if I source the file: >> source("H:/user/R/Adrian/RIB/R/twsConnect.R") >> tws <- twsConnect() >> tws > Object of class "twsConnect": > clientId = 0 > host = "" > port = 7496 > reference = jobjRef >> >> tws at reference > [1] "Java-Object{dev.AAD_Trader at 12558d6}" >> > Things work as I want, I have the connection. What does source do, > that I > miss when packaging? > > My NAMESPACE file is: > exportPattern("^[^\\.]") > > exportClasses("twsConnect", "twsContract", "twsExecutionFilter", > "twsOrder") > > exportMethods("show") > > My .onLoad function contains ".jpackage(pkgname)". > > I tried to package just the class twsConnect without the slot > reference, > and things worked out fine. I tried to say that twsConnect contains > "jobjRef" but did not have much success. > > > Thanks a lot, > Adrian Dragulescu > > ______________________________________________ > R-devel at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel > >