@@ -19,8 +19,13 @@ package org.apache.spark.repl
19
19
20
20
import java .io .File
21
21
import java .net .{URL , URLClassLoader }
22
+ import java .nio .charset .StandardCharsets
23
+ import java .util
24
+
25
+ import com .google .common .io .Files
22
26
23
27
import scala .concurrent .duration ._
28
+ import scala .io .Source
24
29
import scala .language .implicitConversions
25
30
import scala .language .postfixOps
26
31
@@ -41,6 +46,7 @@ class ExecutorClassLoaderSuite
41
46
42
47
val childClassNames = List (" ReplFakeClass1" , " ReplFakeClass2" )
43
48
val parentClassNames = List (" ReplFakeClass1" , " ReplFakeClass2" , " ReplFakeClass3" )
49
+ val parentResourceNames = List (" fake-resource.txt" )
44
50
var tempDir1 : File = _
45
51
var tempDir2 : File = _
46
52
var url1 : String = _
@@ -54,6 +60,9 @@ class ExecutorClassLoaderSuite
54
60
url1 = " file://" + tempDir1
55
61
urls2 = List (tempDir2.toURI.toURL).toArray
56
62
childClassNames.foreach(TestUtils .createCompiledClass(_, tempDir1, " 1" ))
63
+ parentResourceNames.foreach { x =>
64
+ Files .write(" resource" .getBytes(StandardCharsets .UTF_8 ), new File (tempDir2, x))
65
+ }
57
66
parentClassNames.foreach(TestUtils .createCompiledClass(_, tempDir2, " 2" ))
58
67
}
59
68
@@ -99,6 +108,26 @@ class ExecutorClassLoaderSuite
99
108
}
100
109
}
101
110
111
+ test(" resource from parent" ) {
112
+ val parentLoader = new URLClassLoader (urls2, null )
113
+ val classLoader = new ExecutorClassLoader (new SparkConf (), url1, parentLoader, true )
114
+ val resourceName : String = parentResourceNames.head
115
+ val is = classLoader.getResourceAsStream(resourceName)
116
+ assert(is != null , s " Resource $resourceName not found " )
117
+ val content = Source .fromInputStream(is, " UTF-8" ).getLines().next()
118
+ assert(content.contains(" resource" ), " File doesn't contain 'resource'" )
119
+ }
120
+
121
+ test(" resources from parent" ) {
122
+ val parentLoader = new URLClassLoader (urls2, null )
123
+ val classLoader = new ExecutorClassLoader (new SparkConf (), url1, parentLoader, true )
124
+ val resourceName : String = parentResourceNames.head
125
+ val resources : util.Enumeration [URL ] = classLoader.getResources(resourceName)
126
+ assert(resources.hasMoreElements, s " Resource $resourceName not found " )
127
+ val fileReader = Source .fromInputStream(resources.nextElement().openStream()).bufferedReader()
128
+ assert(fileReader.readLine().contains(" resource" ), " File doesn't contain 'resource'" )
129
+ }
130
+
102
131
test(" failing to fetch classes from HTTP server should not leak resources (SPARK-6209)" ) {
103
132
// This is a regression test for SPARK-6209, a bug where each failed attempt to load a class
104
133
// from the driver's class server would leak a HTTP connection, causing the class server's
0 commit comments