Skip to content

Commit 976a43d

Browse files
committed
[SPARK-16581][SPARKR] Make JVM backend calling functions public
## What changes were proposed in this pull request? This change exposes a public API in SparkR to create objects, call methods on the Spark driver JVM ## How was this patch tested? (Please explain how this patch was tested. E.g. unit tests, integration tests, manual tests) Unit tests, CRAN checks Author: Shivaram Venkataraman <[email protected]> Closes #14775 from shivaram/sparkr-java-api. (cherry picked from commit 736a791) Signed-off-by: Shivaram Venkataraman <[email protected]>
1 parent 3d283f6 commit 976a43d

File tree

4 files changed

+167
-2
lines changed

4 files changed

+167
-2
lines changed

R/pkg/DESCRIPTION

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ Package: SparkR
22
Type: Package
33
Title: R Frontend for Apache Spark
44
Version: 2.0.0
5-
Date: 2016-07-07
5+
Date: 2016-08-27
66
Authors@R: c(person("Shivaram", "Venkataraman", role = c("aut", "cre"),
77
email = "[email protected]"),
88
person("Xiangrui", "Meng", role = "aut",
@@ -11,7 +11,7 @@ Authors@R: c(person("Shivaram", "Venkataraman", role = c("aut", "cre"),
1111
email = "[email protected]"),
1212
person(family = "The Apache Software Foundation", role = c("aut", "cph")))
1313
URL: http://www.apache.org/ http://spark.apache.org/
14-
BugReports: https://issues.apache.org/jira/secure/CreateIssueDetails!init.jspa?pid=12315420&components=12325400&issuetype=4
14+
BugReports: https://cwiki.apache.org/confluence/display/SPARK/Contributing+to+Spark#ContributingtoSpark-ContributingBugReports
1515
Depends:
1616
R (>= 3.0),
1717
methods
@@ -39,6 +39,7 @@ Collate:
3939
'deserialize.R'
4040
'functions.R'
4141
'install.R'
42+
'jvm.R'
4243
'mllib.R'
4344
'serialize.R'
4445
'sparkR.R'

R/pkg/NAMESPACE

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -357,4 +357,8 @@ S3method(structField, jobj)
357357
S3method(structType, jobj)
358358
S3method(structType, structField)
359359

360+
export("sparkR.newJObject")
361+
export("sparkR.callJMethod")
362+
export("sparkR.callJStatic")
363+
360364
export("install.spark")

R/pkg/R/jvm.R

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
#
2+
# Licensed to the Apache Software Foundation (ASF) under one or more
3+
# contributor license agreements. See the NOTICE file distributed with
4+
# this work for additional information regarding copyright ownership.
5+
# The ASF licenses this file to You under the Apache License, Version 2.0
6+
# (the "License"); you may not use this file except in compliance with
7+
# the License. You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
#
17+
18+
# Methods to directly access the JVM running the SparkR backend.
19+
20+
#' Call Java Methods
21+
#'
22+
#' Call a Java method in the JVM running the Spark driver. The return
23+
#' values are automatically converted to R objects for simple objects. Other
24+
#' values are returned as "jobj" which are references to objects on JVM.
25+
#'
26+
#' @details
27+
#' This is a low level function to access the JVM directly and should only be used
28+
#' for advanced use cases. The arguments and return values that are primitive R
29+
#' types (like integer, numeric, character, lists) are automatically translated to/from
30+
#' Java types (like Integer, Double, String, Array). A full list can be found in
31+
#' serialize.R and deserialize.R in the Apache Spark code base.
32+
#'
33+
#' @param x object to invoke the method on. Should be a "jobj" created by newJObject.
34+
#' @param methodName method name to call.
35+
#' @param ... parameters to pass to the Java method.
36+
#' @return the return value of the Java method. Either returned as a R object
37+
#' if it can be deserialized or returned as a "jobj". See details section for more.
38+
#' @export
39+
#' @seealso \link{sparkR.callJStatic}, \link{sparkR.newJObject}
40+
#' @rdname sparkR.callJMethod
41+
#' @examples
42+
#' \dontrun{
43+
#' sparkR.session() # Need to have a Spark JVM running before calling newJObject
44+
#' # Create a Java ArrayList and populate it
45+
#' jarray <- sparkR.newJObject("java.util.ArrayList")
46+
#' sparkR.callJMethod(jarray, "add", 42L)
47+
#' sparkR.callJMethod(jarray, "get", 0L) # Will print 42
48+
#' }
49+
#' @note sparkR.callJMethod since 2.0.1
50+
sparkR.callJMethod <- function(x, methodName, ...) {
51+
callJMethod(x, methodName, ...)
52+
}
53+
54+
#' Call Static Java Methods
55+
#'
56+
#' Call a static method in the JVM running the Spark driver. The return
57+
#' value is automatically converted to R objects for simple objects. Other
58+
#' values are returned as "jobj" which are references to objects on JVM.
59+
#'
60+
#' @details
61+
#' This is a low level function to access the JVM directly and should only be used
62+
#' for advanced use cases. The arguments and return values that are primitive R
63+
#' types (like integer, numeric, character, lists) are automatically translated to/from
64+
#' Java types (like Integer, Double, String, Array). A full list can be found in
65+
#' serialize.R and deserialize.R in the Apache Spark code base.
66+
#'
67+
#' @param x fully qualified Java class name that contains the static method to invoke.
68+
#' @param methodName name of static method to invoke.
69+
#' @param ... parameters to pass to the Java method.
70+
#' @return the return value of the Java method. Either returned as a R object
71+
#' if it can be deserialized or returned as a "jobj". See details section for more.
72+
#' @export
73+
#' @seealso \link{sparkR.callJMethod}, \link{sparkR.newJObject}
74+
#' @rdname sparkR.callJStatic
75+
#' @examples
76+
#' \dontrun{
77+
#' sparkR.session() # Need to have a Spark JVM running before calling callJStatic
78+
#' sparkR.callJStatic("java.lang.System", "currentTimeMillis")
79+
#' sparkR.callJStatic("java.lang.System", "getProperty", "java.home")
80+
#' }
81+
#' @note sparkR.callJStatic since 2.0.1
82+
sparkR.callJStatic <- function(x, methodName, ...) {
83+
callJStatic(x, methodName, ...)
84+
}
85+
86+
#' Create Java Objects
87+
#'
88+
#' Create a new Java object in the JVM running the Spark driver. The return
89+
#' value is automatically converted to an R object for simple objects. Other
90+
#' values are returned as a "jobj" which is a reference to an object on JVM.
91+
#'
92+
#' @details
93+
#' This is a low level function to access the JVM directly and should only be used
94+
#' for advanced use cases. The arguments and return values that are primitive R
95+
#' types (like integer, numeric, character, lists) are automatically translated to/from
96+
#' Java types (like Integer, Double, String, Array). A full list can be found in
97+
#' serialize.R and deserialize.R in the Apache Spark code base.
98+
#'
99+
#' @param x fully qualified Java class name.
100+
#' @param ... arguments to be passed to the constructor.
101+
#' @return the object created. Either returned as a R object
102+
#' if it can be deserialized or returned as a "jobj". See details section for more.
103+
#' @export
104+
#' @seealso \link{sparkR.callJMethod}, \link{sparkR.callJStatic}
105+
#' @rdname sparkR.newJObject
106+
#' @examples
107+
#' \dontrun{
108+
#' sparkR.session() # Need to have a Spark JVM running before calling newJObject
109+
#' # Create a Java ArrayList and populate it
110+
#' jarray <- sparkR.newJObject("java.util.ArrayList")
111+
#' sparkR.callJMethod(jarray, "add", 42L)
112+
#' sparkR.callJMethod(jarray, "get", 0L) # Will print 42
113+
#' }
114+
#' @note sparkR.newJObject since 2.0.1
115+
sparkR.newJObject <- function(x, ...) {
116+
newJObject(x, ...)
117+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
#
2+
# Licensed to the Apache Software Foundation (ASF) under one or more
3+
# contributor license agreements. See the NOTICE file distributed with
4+
# this work for additional information regarding copyright ownership.
5+
# The ASF licenses this file to You under the Apache License, Version 2.0
6+
# (the "License"); you may not use this file except in compliance with
7+
# the License. You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
#
17+
18+
context("JVM API")
19+
20+
sparkSession <- sparkR.session(enableHiveSupport = FALSE)
21+
22+
test_that("Create and call methods on object", {
23+
jarr <- newJObject("java.util.ArrayList")
24+
# Add an element to the array
25+
callJMethod(jarr, "add", 1L)
26+
# Check if get returns the same element
27+
expect_equal(callJMethod(jarr, "get", 0L), 1L)
28+
})
29+
30+
test_that("Call static methods", {
31+
# Convert a boolean to a string
32+
strTrue <- callJStatic("java.lang.String", "valueOf", TRUE)
33+
expect_equal(strTrue, "true")
34+
})
35+
36+
test_that("Manually garbage collect objects", {
37+
jarr <- newJObject("java.util.ArrayList")
38+
cleanup.jobj(jarr)
39+
# Using a jobj after GC should throw an error
40+
expect_error(print(jarr), "Error in invokeJava.*")
41+
})
42+
43+
sparkR.session.stop()

0 commit comments

Comments
 (0)