aboutsummaryrefslogtreecommitdiff
path: root/repl/src/main
diff options
context:
space:
mode:
Diffstat (limited to 'repl/src/main')
-rw-r--r--repl/src/main/scala/org/apache/spark/repl/ExecutorClassLoader.scala39
1 files changed, 30 insertions, 9 deletions
diff --git a/repl/src/main/scala/org/apache/spark/repl/ExecutorClassLoader.scala b/repl/src/main/scala/org/apache/spark/repl/ExecutorClassLoader.scala
index bf73800388..a30dcfdcec 100644
--- a/repl/src/main/scala/org/apache/spark/repl/ExecutorClassLoader.scala
+++ b/repl/src/main/scala/org/apache/spark/repl/ExecutorClassLoader.scala
@@ -26,21 +26,23 @@ import org.apache.hadoop.fs.{FileSystem, Path}
import org.apache.spark.SparkEnv
import org.apache.spark.util.Utils
-
+import org.apache.spark.util.ParentClassLoader
import com.esotericsoftware.reflectasm.shaded.org.objectweb.asm._
import com.esotericsoftware.reflectasm.shaded.org.objectweb.asm.Opcodes._
-
/**
* A ClassLoader that reads classes from a Hadoop FileSystem or HTTP URI,
- * used to load classes defined by the interpreter when the REPL is used
- */
-class ExecutorClassLoader(classUri: String, parent: ClassLoader)
-extends ClassLoader(parent) {
+ * used to load classes defined by the interpreter when the REPL is used.
+ * Allows the user to specify if user class path should be first
+ */
+class ExecutorClassLoader(classUri: String, parent: ClassLoader,
+ userClassPathFirst: Boolean) extends ClassLoader {
val uri = new URI(classUri)
val directory = uri.getPath
+ val parentLoader = new ParentClassLoader(parent)
+
// Hadoop FileSystem object for our URI, if it isn't using HTTP
var fileSystem: FileSystem = {
if (uri.getScheme() == "http") {
@@ -49,8 +51,27 @@ extends ClassLoader(parent) {
FileSystem.get(uri, new Configuration())
}
}
-
+
override def findClass(name: String): Class[_] = {
+ userClassPathFirst match {
+ case true => findClassLocally(name).getOrElse(parentLoader.loadClass(name))
+ case false => {
+ try {
+ parentLoader.loadClass(name)
+ } catch {
+ case e: ClassNotFoundException => {
+ val classOption = findClassLocally(name)
+ classOption match {
+ case None => throw new ClassNotFoundException(name, e)
+ case Some(a) => a
+ }
+ }
+ }
+ }
+ }
+ }
+
+ def findClassLocally(name: String): Option[Class[_]] = {
try {
val pathInDirectory = name.replace('.', '/') + ".class"
val inputStream = {
@@ -68,9 +89,9 @@ extends ClassLoader(parent) {
}
val bytes = readAndTransformClass(name, inputStream)
inputStream.close()
- return defineClass(name, bytes, 0, bytes.length)
+ Some(defineClass(name, bytes, 0, bytes.length))
} catch {
- case e: Exception => throw new ClassNotFoundException(name, e)
+ case e: Exception => None
}
}