From 472072ae12c146bd1a7a844337c4496bbdfdbd2d Mon Sep 17 00:00:00 2001 From: Shivaram Venkataraman Date: Mon, 22 Aug 2016 12:37:38 -0700 Subject: [PATCH 1/6] First cut of making JVM functions public --- R/pkg/NAMESPACE | 5 +++++ R/pkg/R/backend.R | 48 ++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 48 insertions(+), 5 deletions(-) diff --git a/R/pkg/NAMESPACE b/R/pkg/NAMESPACE index e1b87b28d35ae..06d7d41f4f9b2 100644 --- a/R/pkg/NAMESPACE +++ b/R/pkg/NAMESPACE @@ -359,4 +359,9 @@ S3method(structField, jobj) S3method(structType, jobj) S3method(structType, structField) +S3method(cleanup, jobj) +export("newJObject") +export("callJMethod") +export("callJStatic") + export("install.spark") diff --git a/R/pkg/R/backend.R b/R/pkg/R/backend.R index 03e70bb2cb82e..ad4907e21c74e 100644 --- a/R/pkg/R/backend.R +++ b/R/pkg/R/backend.R @@ -25,9 +25,21 @@ isInstanceOf <- function(jobj, className) { callJMethod(cls, "isInstance", jobj) } -# Call a Java method named methodName on the object -# specified by objId. objId should be a "jobj" returned -# from the SparkRBackend. +#' Call a Java method in the JVM running the Spark driver. +#' +#' @param objId object to invoke the method on. Should be a "jobj" created by newJObject. +#' @param methodName method name to call. +#' @param ... parameters to pass to the Java method. +#' @export +#' @seealso callJStatic, newJObject +#' @examples +#' \dontrun{ +#' sparkR.session() # Need to have a Spark JVM running before calling newJObject +#' # Create a Java ArrayList and populate it +#' jarray <- newJObject("java.util.ArrayList") +#' callJMethod(jarray, "add", 42L) +#' callJMethod(jarray, "get", 0L) # Will print 42 +#' } callJMethod <- function(objId, methodName, ...) { stopifnot(class(objId) == "jobj") if (!isValidJobj(objId)) { @@ -37,12 +49,38 @@ callJMethod <- function(objId, methodName, ...) { invokeJava(isStatic = FALSE, objId$id, methodName, ...) } -# Call a static method on a specified className +#' Call a static method in the JVM running the Spark driver. +#' +#' @param className class containing the static method to invoke. +#' @param methodName name of static method to invoke. +#' @param ... parameters to pass to the Java method. +#' @export +#' @seealso callJMethod, newJObject +#' @examples +#' \dontrun{ +#' sparkR.session() # Need to have a Spark JVM running before calling callJStatic +#' callJStatic("java.lang.System", "currentTimeMillis") +#' callJStatic("java.lang.System", "getProperty", "java.home") +#' } callJStatic <- function(className, methodName, ...) { invokeJava(isStatic = TRUE, className, methodName, ...) } -# Create a new object of the specified class name +#' Create a new Java object in the JVM running the Spark driver. +#' +#' @param className name of the class to create +#' @param ... arguments to be passed to the constructor +#' @export +#' @seealso callJMethod, callJStatic +#' @examples +#' \dontrun{ +#' sparkR.session() # Need to have a Spark JVM running before calling newJObject +#' # Create a Java ArrayList and populate it +#' jarray <- newJObject("java.util.ArrayList") +#' callJMethod(jarray, "add", 42L) +#' callJMethod(jarray, "get", 0L) # Will print 42 +#' } +#' @note newJObject since 2.0.1 newJObject <- function(className, ...) { invokeJava(isStatic = TRUE, className, methodName = "", ...) } From d772285ab1d6ed7facd5db05b772ba752428a30f Mon Sep 17 00:00:00 2001 From: Shivaram Venkataraman Date: Tue, 23 Aug 2016 10:29:43 -0700 Subject: [PATCH 2/6] Improve documentation for JVM methods --- R/pkg/NAMESPACE | 2 +- R/pkg/R/backend.R | 6 ++++++ R/pkg/R/jobj.R | 15 ++++++++++++++- 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/R/pkg/NAMESPACE b/R/pkg/NAMESPACE index 06d7d41f4f9b2..049e10483b988 100644 --- a/R/pkg/NAMESPACE +++ b/R/pkg/NAMESPACE @@ -359,9 +359,9 @@ S3method(structField, jobj) S3method(structType, jobj) S3method(structType, structField) -S3method(cleanup, jobj) export("newJObject") export("callJMethod") export("callJStatic") +export("cleanup.jobj") export("install.spark") diff --git a/R/pkg/R/backend.R b/R/pkg/R/backend.R index ad4907e21c74e..4b85e192a398d 100644 --- a/R/pkg/R/backend.R +++ b/R/pkg/R/backend.R @@ -25,6 +25,8 @@ isInstanceOf <- function(jobj, className) { callJMethod(cls, "isInstance", jobj) } +#' Call Java Methods +#' #' Call a Java method in the JVM running the Spark driver. #' #' @param objId object to invoke the method on. Should be a "jobj" created by newJObject. @@ -49,6 +51,8 @@ callJMethod <- function(objId, methodName, ...) { invokeJava(isStatic = FALSE, objId$id, methodName, ...) } +#' Call Static Java Methods +#' #' Call a static method in the JVM running the Spark driver. #' #' @param className class containing the static method to invoke. @@ -66,6 +70,8 @@ callJStatic <- function(className, methodName, ...) { invokeJava(isStatic = TRUE, className, methodName, ...) } +#' Create Java Objects +#' #' Create a new Java object in the JVM running the Spark driver. #' #' @param className name of the class to create diff --git a/R/pkg/R/jobj.R b/R/pkg/R/jobj.R index 4905e1fe5c61f..054342d293a90 100644 --- a/R/pkg/R/jobj.R +++ b/R/pkg/R/jobj.R @@ -82,7 +82,20 @@ getClassName.jobj <- function(x) { callJMethod(cls, "getName") } -cleanup.jobj <- function(jobj) { +#' Garbage collect Java Objects +#' +#' Garbage collect an object allocated on Spark driver JVM heap. +#' +#' cleanup.jobj is a low level method that lets developers manually garbage collect objects +#' allocated using newJObject. This is only to be used for advanced use cases as objects allocated +#' on the JVM heap are automatically garbage collected when the corresponding R reference goes out +#' of scope. +#' +#' @param x the Java object that should be garbage collected. +#' @note cleanup.jobj since 2.0.1 +#' @export +cleanup.jobj <- function(x) { + jobj <- x if (isValidJobj(jobj)) { objId <- jobj$id # If we don't know anything about this jobj, ignore it From d267f2f271aa4e3f7bd8542fa1772ecc978eeee8 Mon Sep 17 00:00:00 2001 From: Shivaram Venkataraman Date: Tue, 23 Aug 2016 12:40:39 -0700 Subject: [PATCH 3/6] Add unit tests for JVM API --- R/pkg/inst/tests/testthat/test_jvm_api.R | 41 ++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 R/pkg/inst/tests/testthat/test_jvm_api.R diff --git a/R/pkg/inst/tests/testthat/test_jvm_api.R b/R/pkg/inst/tests/testthat/test_jvm_api.R new file mode 100644 index 0000000000000..27dc90656368a --- /dev/null +++ b/R/pkg/inst/tests/testthat/test_jvm_api.R @@ -0,0 +1,41 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +context("JVM API") + +sparkSession <- sparkR.session(enableHiveSupport = FALSE) + +test_that("Create and call methods on object", { + jarr <- newJObject("java.util.ArrayList") + # Add an element to the array + callJMethod(jarr, "add", 1L) + # Check if get returns the same element + expect_equal(callJMethod(jarr, "get", 0L), 1L) +}) + +test_that("Call static methods", { + # Convert a boolean to a string + strTrue <- callJStatic("java.lang.String", "valueOf", TRUE) + expect_equal(strTrue, "true") +}) + +test_that("Manually garbage collect objects", { + jarr <- newJObject("java.util.ArrayList") + cleanup.jobj(jarr) + # Using a jobj after GC should throw an error + expect_error(print(jarr), "Error in invokeJava.*") +}) From 0959208424e085cc3769e03d4b67779e08296009 Mon Sep 17 00:00:00 2001 From: Shivaram Venkataraman Date: Sat, 27 Aug 2016 15:03:03 -0700 Subject: [PATCH 4/6] Create wrappers for JVM calls. Address code review comments --- R/pkg/DESCRIPTION | 3 +- R/pkg/NAMESPACE | 7 +- R/pkg/R/backend.R | 54 ++------------ R/pkg/R/jobj.R | 15 +--- R/pkg/R/jvm.R | 93 ++++++++++++++++++++++++ R/pkg/inst/tests/testthat/test_jvm_api.R | 2 + 6 files changed, 106 insertions(+), 68 deletions(-) create mode 100644 R/pkg/R/jvm.R diff --git a/R/pkg/DESCRIPTION b/R/pkg/DESCRIPTION index e5afed2d0a93e..1f1d72557dc72 100644 --- a/R/pkg/DESCRIPTION +++ b/R/pkg/DESCRIPTION @@ -11,7 +11,7 @@ Authors@R: c(person("Shivaram", "Venkataraman", role = c("aut", "cre"), email = "felixcheung@apache.org"), person(family = "The Apache Software Foundation", role = c("aut", "cph"))) URL: http://www.apache.org/ http://spark.apache.org/ -BugReports: https://issues.apache.org/jira/secure/CreateIssueDetails!init.jspa?pid=12315420&components=12325400&issuetype=4 +BugReports: https://issues.apache.org/jira/browse/SPARK Depends: R (>= 3.0), methods @@ -39,6 +39,7 @@ Collate: 'deserialize.R' 'functions.R' 'install.R' + 'jvm.R' 'mllib.R' 'serialize.R' 'sparkR.R' diff --git a/R/pkg/NAMESPACE b/R/pkg/NAMESPACE index 7b77f07cb9458..42db5efc3ce42 100644 --- a/R/pkg/NAMESPACE +++ b/R/pkg/NAMESPACE @@ -363,9 +363,8 @@ S3method(structField, jobj) S3method(structType, jobj) S3method(structType, structField) -export("newJObject") -export("callJMethod") -export("callJStatic") -export("cleanup.jobj") +export("sparkR.newJObject") +export("sparkR.callJMethod") +export("sparkR.callJStatic") export("install.spark") diff --git a/R/pkg/R/backend.R b/R/pkg/R/backend.R index 4b85e192a398d..03e70bb2cb82e 100644 --- a/R/pkg/R/backend.R +++ b/R/pkg/R/backend.R @@ -25,23 +25,9 @@ isInstanceOf <- function(jobj, className) { callJMethod(cls, "isInstance", jobj) } -#' Call Java Methods -#' -#' Call a Java method in the JVM running the Spark driver. -#' -#' @param objId object to invoke the method on. Should be a "jobj" created by newJObject. -#' @param methodName method name to call. -#' @param ... parameters to pass to the Java method. -#' @export -#' @seealso callJStatic, newJObject -#' @examples -#' \dontrun{ -#' sparkR.session() # Need to have a Spark JVM running before calling newJObject -#' # Create a Java ArrayList and populate it -#' jarray <- newJObject("java.util.ArrayList") -#' callJMethod(jarray, "add", 42L) -#' callJMethod(jarray, "get", 0L) # Will print 42 -#' } +# Call a Java method named methodName on the object +# specified by objId. objId should be a "jobj" returned +# from the SparkRBackend. callJMethod <- function(objId, methodName, ...) { stopifnot(class(objId) == "jobj") if (!isValidJobj(objId)) { @@ -51,42 +37,12 @@ callJMethod <- function(objId, methodName, ...) { invokeJava(isStatic = FALSE, objId$id, methodName, ...) } -#' Call Static Java Methods -#' -#' Call a static method in the JVM running the Spark driver. -#' -#' @param className class containing the static method to invoke. -#' @param methodName name of static method to invoke. -#' @param ... parameters to pass to the Java method. -#' @export -#' @seealso callJMethod, newJObject -#' @examples -#' \dontrun{ -#' sparkR.session() # Need to have a Spark JVM running before calling callJStatic -#' callJStatic("java.lang.System", "currentTimeMillis") -#' callJStatic("java.lang.System", "getProperty", "java.home") -#' } +# Call a static method on a specified className callJStatic <- function(className, methodName, ...) { invokeJava(isStatic = TRUE, className, methodName, ...) } -#' Create Java Objects -#' -#' Create a new Java object in the JVM running the Spark driver. -#' -#' @param className name of the class to create -#' @param ... arguments to be passed to the constructor -#' @export -#' @seealso callJMethod, callJStatic -#' @examples -#' \dontrun{ -#' sparkR.session() # Need to have a Spark JVM running before calling newJObject -#' # Create a Java ArrayList and populate it -#' jarray <- newJObject("java.util.ArrayList") -#' callJMethod(jarray, "add", 42L) -#' callJMethod(jarray, "get", 0L) # Will print 42 -#' } -#' @note newJObject since 2.0.1 +# Create a new object of the specified class name newJObject <- function(className, ...) { invokeJava(isStatic = TRUE, className, methodName = "", ...) } diff --git a/R/pkg/R/jobj.R b/R/pkg/R/jobj.R index 054342d293a90..4905e1fe5c61f 100644 --- a/R/pkg/R/jobj.R +++ b/R/pkg/R/jobj.R @@ -82,20 +82,7 @@ getClassName.jobj <- function(x) { callJMethod(cls, "getName") } -#' Garbage collect Java Objects -#' -#' Garbage collect an object allocated on Spark driver JVM heap. -#' -#' cleanup.jobj is a low level method that lets developers manually garbage collect objects -#' allocated using newJObject. This is only to be used for advanced use cases as objects allocated -#' on the JVM heap are automatically garbage collected when the corresponding R reference goes out -#' of scope. -#' -#' @param x the Java object that should be garbage collected. -#' @note cleanup.jobj since 2.0.1 -#' @export -cleanup.jobj <- function(x) { - jobj <- x +cleanup.jobj <- function(jobj) { if (isValidJobj(jobj)) { objId <- jobj$id # If we don't know anything about this jobj, ignore it diff --git a/R/pkg/R/jvm.R b/R/pkg/R/jvm.R new file mode 100644 index 0000000000000..7ef2a9e5c0b77 --- /dev/null +++ b/R/pkg/R/jvm.R @@ -0,0 +1,93 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# Methods to directly access the JVM running the SparkR backend. + +#' Call Java Methods +#' +#' Call a Java method in the JVM running the Spark driver. The return +#' values are automatically converted to R objects for simple objects. Other +#' values are returned as "jobj" which are references to objects on JVM. +#' +#' @param x object to invoke the method on. Should be a "jobj" created by newJObject. +#' @param methodName method name to call. +#' @param ... parameters to pass to the Java method. +#' @return the return value of the Java method. Either returned as a R object +#' if it can be deserialized or returned as a "jobj". +#' @export +#' @seealso \link{sparkR.callJStatic}, \link{sparkR.newJObject} +#' @examples +#' \dontrun{ +#' sparkR.session() # Need to have a Spark JVM running before calling newJObject +#' # Create a Java ArrayList and populate it +#' jarray <- sparkR.newJObject("java.util.ArrayList") +#' sparkR.callJMethod(jarray, "add", 42L) +#' sparkR.callJMethod(jarray, "get", 0L) # Will print 42 +#' } +#' @note sparkR.callJMethod since 2.0.1 +sparkR.callJMethod <- function(x, methodName, ...) { + callJMethod(x, methodName, ...) +} + +#' Call Static Java Methods +#' +#' Call a static method in the JVM running the Spark driver. The return +#' value is automatically converted to R objects for simple objects. Other +#' values are returned as "jobj" which are references to objects on JVM. +#' +#' @param x fully qualified Java class name that contains the static method to invoke. +#' @param methodName name of static method to invoke. +#' @param ... parameters to pass to the Java method. +#' @return the return value of the Java method. Either returned as a R object +#' if it can be deserialized or returned as a "jobj". +#' @export +#' @seealso \link{sparkR.callJMethod}, \link{sparkR.newJObject} +#' @examples +#' \dontrun{ +#' sparkR.session() # Need to have a Spark JVM running before calling callJStatic +#' sparkR.callJStatic("java.lang.System", "currentTimeMillis") +#' sparkR.callJStatic("java.lang.System", "getProperty", "java.home") +#' } +#' @note sparkR.callJStatic since 2.0.1 +sparkR.callJStatic <- function(x, methodName, ...) { + callJStatic(x, methodName, ...) +} + +#' Create Java Objects +#' +#' Create a new Java object in the JVM running the Spark driver. The return +#' value is automatically converted to an R object for simple objects. Other +#' values are returned as a "jobj" which is a reference to an object on JVM. +#' +#' @param x fully qualified Java class name. +#' @param ... arguments to be passed to the constructor. +#' @return the object created. Either returned as a R object +#' if it can be deserialized or returned as a "jobj". +#' @export +#' @seealso \link{sparkR.callJMethod}, \link{sparkR.callJStatic} +#' @examples +#' \dontrun{ +#' sparkR.session() # Need to have a Spark JVM running before calling newJObject +#' # Create a Java ArrayList and populate it +#' jarray <- sparkR.newJObject("java.util.ArrayList") +#' sparkR.callJMethod(jarray, "add", 42L) +#' sparkR.callJMethod(jarray, "get", 0L) # Will print 42 +#' } +#' @note sparkR.newJObject since 2.0.1 +sparkR.newJObject <- function(x, ...) { + newJObject(x, ...) +} diff --git a/R/pkg/inst/tests/testthat/test_jvm_api.R b/R/pkg/inst/tests/testthat/test_jvm_api.R index 27dc90656368a..151c52906bdb8 100644 --- a/R/pkg/inst/tests/testthat/test_jvm_api.R +++ b/R/pkg/inst/tests/testthat/test_jvm_api.R @@ -39,3 +39,5 @@ test_that("Manually garbage collect objects", { # Using a jobj after GC should throw an error expect_error(print(jarr), "Error in invokeJava.*") }) + +sparkR.session.stop() From 448de0c2faf72d3e1fc4d08aa88cd41e8b20c79f Mon Sep 17 00:00:00 2001 From: Shivaram Venkataraman Date: Sat, 27 Aug 2016 15:15:49 -0700 Subject: [PATCH 5/6] Update bug report URL and date in DESCRIPTION --- R/pkg/DESCRIPTION | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/R/pkg/DESCRIPTION b/R/pkg/DESCRIPTION index 1f1d72557dc72..7dbba4e89b00e 100644 --- a/R/pkg/DESCRIPTION +++ b/R/pkg/DESCRIPTION @@ -2,7 +2,7 @@ Package: SparkR Type: Package Title: R Frontend for Apache Spark Version: 2.0.0 -Date: 2016-07-07 +Date: 2016-08-27 Authors@R: c(person("Shivaram", "Venkataraman", role = c("aut", "cre"), email = "shivaram@cs.berkeley.edu"), person("Xiangrui", "Meng", role = "aut", @@ -11,7 +11,7 @@ Authors@R: c(person("Shivaram", "Venkataraman", role = c("aut", "cre"), email = "felixcheung@apache.org"), person(family = "The Apache Software Foundation", role = c("aut", "cph"))) URL: http://www.apache.org/ http://spark.apache.org/ -BugReports: https://issues.apache.org/jira/browse/SPARK +BugReports: http://issues.apache.org/jira/browse/SPARK Depends: R (>= 3.0), methods From d1ec80b3a57b0610ce0367447e9802923ad02ae9 Mon Sep 17 00:00:00 2001 From: Shivaram Venkataraman Date: Mon, 29 Aug 2016 10:55:26 -0700 Subject: [PATCH 6/6] Address code review comments --- R/pkg/DESCRIPTION | 2 +- R/pkg/R/jvm.R | 30 +++++++++++++++++++++++++++--- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/R/pkg/DESCRIPTION b/R/pkg/DESCRIPTION index 7dbba4e89b00e..5a83883089e0e 100644 --- a/R/pkg/DESCRIPTION +++ b/R/pkg/DESCRIPTION @@ -11,7 +11,7 @@ Authors@R: c(person("Shivaram", "Venkataraman", role = c("aut", "cre"), email = "felixcheung@apache.org"), person(family = "The Apache Software Foundation", role = c("aut", "cph"))) URL: http://www.apache.org/ http://spark.apache.org/ -BugReports: http://issues.apache.org/jira/browse/SPARK +BugReports: https://cwiki.apache.org/confluence/display/SPARK/Contributing+to+Spark#ContributingtoSpark-ContributingBugReports Depends: R (>= 3.0), methods diff --git a/R/pkg/R/jvm.R b/R/pkg/R/jvm.R index 7ef2a9e5c0b77..bb5c77544a3da 100644 --- a/R/pkg/R/jvm.R +++ b/R/pkg/R/jvm.R @@ -23,13 +23,21 @@ #' values are automatically converted to R objects for simple objects. Other #' values are returned as "jobj" which are references to objects on JVM. #' +#' @details +#' This is a low level function to access the JVM directly and should only be used +#' for advanced use cases. The arguments and return values that are primitive R +#' types (like integer, numeric, character, lists) are automatically translated to/from +#' Java types (like Integer, Double, String, Array). A full list can be found in +#' serialize.R and deserialize.R in the Apache Spark code base. +#' #' @param x object to invoke the method on. Should be a "jobj" created by newJObject. #' @param methodName method name to call. #' @param ... parameters to pass to the Java method. #' @return the return value of the Java method. Either returned as a R object -#' if it can be deserialized or returned as a "jobj". +#' if it can be deserialized or returned as a "jobj". See details section for more. #' @export #' @seealso \link{sparkR.callJStatic}, \link{sparkR.newJObject} +#' @rdname sparkR.callJMethod #' @examples #' \dontrun{ #' sparkR.session() # Need to have a Spark JVM running before calling newJObject @@ -49,13 +57,21 @@ sparkR.callJMethod <- function(x, methodName, ...) { #' value is automatically converted to R objects for simple objects. Other #' values are returned as "jobj" which are references to objects on JVM. #' +#' @details +#' This is a low level function to access the JVM directly and should only be used +#' for advanced use cases. The arguments and return values that are primitive R +#' types (like integer, numeric, character, lists) are automatically translated to/from +#' Java types (like Integer, Double, String, Array). A full list can be found in +#' serialize.R and deserialize.R in the Apache Spark code base. +#' #' @param x fully qualified Java class name that contains the static method to invoke. #' @param methodName name of static method to invoke. #' @param ... parameters to pass to the Java method. #' @return the return value of the Java method. Either returned as a R object -#' if it can be deserialized or returned as a "jobj". +#' if it can be deserialized or returned as a "jobj". See details section for more. #' @export #' @seealso \link{sparkR.callJMethod}, \link{sparkR.newJObject} +#' @rdname sparkR.callJStatic #' @examples #' \dontrun{ #' sparkR.session() # Need to have a Spark JVM running before calling callJStatic @@ -73,12 +89,20 @@ sparkR.callJStatic <- function(x, methodName, ...) { #' value is automatically converted to an R object for simple objects. Other #' values are returned as a "jobj" which is a reference to an object on JVM. #' +#' @details +#' This is a low level function to access the JVM directly and should only be used +#' for advanced use cases. The arguments and return values that are primitive R +#' types (like integer, numeric, character, lists) are automatically translated to/from +#' Java types (like Integer, Double, String, Array). A full list can be found in +#' serialize.R and deserialize.R in the Apache Spark code base. +#' #' @param x fully qualified Java class name. #' @param ... arguments to be passed to the constructor. #' @return the object created. Either returned as a R object -#' if it can be deserialized or returned as a "jobj". +#' if it can be deserialized or returned as a "jobj". See details section for more. #' @export #' @seealso \link{sparkR.callJMethod}, \link{sparkR.callJStatic} +#' @rdname sparkR.newJObject #' @examples #' \dontrun{ #' sparkR.session() # Need to have a Spark JVM running before calling newJObject