Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -19,56 +19,51 @@ package org.apache.spark.executor

import java.net.{URLClassLoader, URL}

import org.apache.spark.util.ParentClassLoader
/**
* A ClassLoader trait that changes the normal delegation scheme.
* Normally, it's (cache, parent, self). GreedyClassLoader uses
* (cache, self, parent). This lets this CL "hide" or "override"
* class defs that also exist in the parent loader.
*/
private[spark] trait GreedyClassLoader extends ClassLoader {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rather than making this a trait, can you just modify ChildExecutorURLClassLoader to have this logic? We don't need it anywhere else at this point, and this is the main intended goal of ChildExecutorURLClassLoader (to do greedy loading like this).

override def loadClass(name: String, resolve: Boolean): Class[_] = {
this.synchronized {
// Check the cache
var c: Class[_] = findLoadedClass(name)
if (c == null) {
try {
// Try loading it ourselves
c = findClass(name)
} catch {
case ignored: ClassNotFoundException =>
}

if (c == null) {
// Finally, try delegating to the parent
c = getParent.loadClass(name)
}
}
if (resolve) {
resolveClass(c)
}
c
}
}
}

/**
* The addURL method in URLClassLoader is protected. We subclass it to make this accessible.
* We also make changes so user classes can come before the default classes.
*/

private[spark] trait MutableURLClassLoader extends ClassLoader {
def addURL(url: URL)
def addURL(url: URL) //XXX: this is sketchy and dangerous. ClassLoader instances aren't designed to be mutable.
def getURLs: Array[URL]
}

private[spark] class ChildExecutorURLClassLoader(urls: Array[URL], parent: ClassLoader)
extends MutableURLClassLoader {

private object userClassLoader extends URLClassLoader(urls, null){
override def addURL(url: URL) {
super.addURL(url)
}
override def findClass(name: String): Class[_] = {
super.findClass(name)
}
}

private val parentClassLoader = new ParentClassLoader(parent)

override def findClass(name: String): Class[_] = {
try {
userClassLoader.findClass(name)
} catch {
case e: ClassNotFoundException => {
parentClassLoader.loadClass(name)
}
}
}

def addURL(url: URL) {
userClassLoader.addURL(url)
}

def getURLs() = {
userClassLoader.getURLs()
}
extends URLClassLoader(urls, parent) with GreedyClassLoader with MutableURLClassLoader {
}

private[spark] class ExecutorURLClassLoader(urls: Array[URL], parent: ClassLoader)
extends URLClassLoader(urls, parent) with MutableURLClassLoader {

override def addURL(url: URL) {
super.addURL(url)
}
}