Skip to content

Commit 4a84d87

Browse files
author
Marcelo Vanzin
committed
Fix the child-first class loader.
The class loader could run into a situation where a class managed by the child class loader referenced a still-unloaded class from the parent class loader. Since the child class loader ("userClassLoader" in the previous code) did not have a parent, finding that class would fail, and the child class would fail to load. A second problem was calling `loadClass()` from a `findClass()` implementation. This could cause the code to try to define the same class more than once. The fix for both is to override `loadClass()` instead of `findClass()`, and implement the "priority inversion" there.
1 parent d0394b8 commit 4a84d87

File tree

1 file changed

+8
-21
lines changed

1 file changed

+8
-21
lines changed

core/src/main/scala/org/apache/spark/executor/ExecutorURLClassLoader.scala

Lines changed: 8 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -35,37 +35,27 @@ private[spark] trait MutableURLClassLoader extends ClassLoader {
3535
}
3636

3737
private[spark] class ChildExecutorURLClassLoader(urls: Array[URL], parent: ClassLoader)
38-
extends MutableURLClassLoader {
39-
40-
private object userClassLoader extends URLClassLoader(urls, null){
41-
override def addURL(url: URL) {
42-
super.addURL(url)
43-
}
44-
override def findClass(name: String): Class[_] = {
45-
super.findClass(name)
46-
}
47-
}
38+
extends URLClassLoader(urls, null) with MutableURLClassLoader {
4839

4940
private val parentClassLoader = new ParentClassLoader(parent)
5041

51-
override def findClass(name: String): Class[_] = {
42+
override def loadClass(name: String, resolve: Boolean): Class[_] = {
5243
try {
53-
userClassLoader.findClass(name)
44+
super.loadClass(name, resolve)
5445
} catch {
55-
case e: ClassNotFoundException => {
46+
case e: ClassNotFoundException =>
5647
parentClassLoader.loadClass(name)
57-
}
5848
}
5949
}
6050

6151
override def getResource(name: String): URL = {
62-
val url = userClassLoader.findResource(name)
52+
val url = super.findResource(name)
6353
val res = if (url != null) url else parentClassLoader.getResource(name)
6454
res
6555
}
6656

6757
override def getResources(name: String): Enumeration[URL] = {
68-
val urls = userClassLoader.findResources(name)
58+
val urls = super.findResources(name)
6959
val res =
7060
if (urls != null && urls.hasMoreElements()) {
7161
urls
@@ -75,13 +65,10 @@ private[spark] class ChildExecutorURLClassLoader(urls: Array[URL], parent: Class
7565
res
7666
}
7767

78-
def addURL(url: URL) {
79-
userClassLoader.addURL(url)
68+
override def addURL(url: URL) {
69+
super.addURL(url)
8070
}
8171

82-
def getURLs() = {
83-
userClassLoader.getURLs()
84-
}
8572
}
8673

8774
private[spark] class ExecutorURLClassLoader(urls: Array[URL], parent: ClassLoader)

0 commit comments

Comments
 (0)