aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--R/pkg/inst/test_support/sparktestjar_2.10-1.0.jarbin0 -> 2886 bytes
-rw-r--r--R/pkg/inst/tests/jarTest.R32
-rw-r--r--R/pkg/inst/tests/test_includeJAR.R37
-rw-r--r--core/src/main/scala/org/apache/spark/api/r/RBackendHandler.scala17
4 files changed, 85 insertions, 1 deletions
diff --git a/R/pkg/inst/test_support/sparktestjar_2.10-1.0.jar b/R/pkg/inst/test_support/sparktestjar_2.10-1.0.jar
new file mode 100644
index 0000000000..1d5c2af631
--- /dev/null
+++ b/R/pkg/inst/test_support/sparktestjar_2.10-1.0.jar
Binary files differ
diff --git a/R/pkg/inst/tests/jarTest.R b/R/pkg/inst/tests/jarTest.R
new file mode 100644
index 0000000000..d68bb20950
--- /dev/null
+++ b/R/pkg/inst/tests/jarTest.R
@@ -0,0 +1,32 @@
+#
+# 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.
+#
+library(SparkR)
+
+sc <- sparkR.init()
+
+helloTest <- SparkR:::callJStatic("sparkR.test.hello",
+ "helloWorld",
+ "Dave")
+
+basicFunction <- SparkR:::callJStatic("sparkR.test.basicFunction",
+ "addStuff",
+ 2L,
+ 2L)
+
+sparkR.stop()
+output <- c(helloTest, basicFunction)
+writeLines(output)
diff --git a/R/pkg/inst/tests/test_includeJAR.R b/R/pkg/inst/tests/test_includeJAR.R
new file mode 100644
index 0000000000..8bc693be20
--- /dev/null
+++ b/R/pkg/inst/tests/test_includeJAR.R
@@ -0,0 +1,37 @@
+#
+# 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("include an external JAR in SparkContext")
+
+runScript <- function() {
+ sparkHome <- Sys.getenv("SPARK_HOME")
+ jarPath <- paste("--jars",
+ shQuote(file.path(sparkHome, "R/lib/SparkR/test_support/sparktestjar_2.10-1.0.jar")))
+ scriptPath <- file.path(sparkHome, "R/lib/SparkR/tests/jarTest.R")
+ submitPath <- file.path(sparkHome, "bin/spark-submit")
+ res <- system2(command = submitPath,
+ args = c(jarPath, scriptPath),
+ stdout = TRUE)
+ tail(res, 2)
+}
+
+test_that("sparkJars tag in SparkContext", {
+ testOutput <- runScript()
+ helloTest <- testOutput[1]
+ expect_true(helloTest == "Hello, Dave")
+ basicFunction <- testOutput[2]
+ expect_true(basicFunction == 4L)
+})
diff --git a/core/src/main/scala/org/apache/spark/api/r/RBackendHandler.scala b/core/src/main/scala/org/apache/spark/api/r/RBackendHandler.scala
index 2e86984c66..4b8f7fe924 100644
--- a/core/src/main/scala/org/apache/spark/api/r/RBackendHandler.scala
+++ b/core/src/main/scala/org/apache/spark/api/r/RBackendHandler.scala
@@ -88,6 +88,21 @@ private[r] class RBackendHandler(server: RBackend)
ctx.close()
}
+ // Looks up a class given a class name. This function first checks the
+ // current class loader and if a class is not found, it looks up the class
+ // in the context class loader. Address [SPARK-5185]
+ def getStaticClass(objId: String): Class[_] = {
+ try {
+ val clsCurrent = Class.forName(objId)
+ clsCurrent
+ } catch {
+ // Use contextLoader if we can't find the JAR in the system class loader
+ case e: ClassNotFoundException =>
+ val clsContext = Class.forName(objId, true, Thread.currentThread().getContextClassLoader)
+ clsContext
+ }
+ }
+
def handleMethodCall(
isStatic: Boolean,
objId: String,
@@ -98,7 +113,7 @@ private[r] class RBackendHandler(server: RBackend)
var obj: Object = null
try {
val cls = if (isStatic) {
- Class.forName(objId)
+ getStaticClass(objId)
} else {
JVMObjectTracker.get(objId) match {
case None => throw new IllegalArgumentException("Object not found " + objId)