@@ -19,8 +19,13 @@ package org.apache.spark.repl
1919
2020import java .io .File
2121import java .net .{URL , URLClassLoader }
22+ import java .nio .charset .StandardCharsets
23+ import java .util
24+
25+ import com .google .common .io .Files
2226
2327import scala .concurrent .duration ._
28+ import scala .io .Source
2429import scala .language .implicitConversions
2530import scala .language .postfixOps
2631
@@ -41,6 +46,7 @@ class ExecutorClassLoaderSuite
4146
4247 val childClassNames = List (" ReplFakeClass1" , " ReplFakeClass2" )
4348 val parentClassNames = List (" ReplFakeClass1" , " ReplFakeClass2" , " ReplFakeClass3" )
49+ val parentResourceNames = List (" fake-resource.txt" )
4450 var tempDir1 : File = _
4551 var tempDir2 : File = _
4652 var url1 : String = _
@@ -54,6 +60,9 @@ class ExecutorClassLoaderSuite
5460 url1 = " file://" + tempDir1
5561 urls2 = List (tempDir2.toURI.toURL).toArray
5662 childClassNames.foreach(TestUtils .createCompiledClass(_, tempDir1, " 1" ))
63+ parentResourceNames.foreach { x =>
64+ Files .write(" resource" .getBytes(StandardCharsets .UTF_8 ), new File (tempDir2, x))
65+ }
5766 parentClassNames.foreach(TestUtils .createCompiledClass(_, tempDir2, " 2" ))
5867 }
5968
@@ -99,6 +108,26 @@ class ExecutorClassLoaderSuite
99108 }
100109 }
101110
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+
102131 test(" failing to fetch classes from HTTP server should not leak resources (SPARK-6209)" ) {
103132 // This is a regression test for SPARK-6209, a bug where each failed attempt to load a class
104133 // from the driver's class server would leak a HTTP connection, causing the class server's
0 commit comments