@@ -24,7 +24,6 @@ import scala.Predef.{println => _, _}
24
24
// scalastyle:on println
25
25
import scala .concurrent .Future
26
26
import scala .reflect .classTag
27
- import scala .reflect .internal .util .ScalaClassLoader .savingContextLoader
28
27
import scala .reflect .io .File
29
28
import scala .tools .nsc .{GenericRunnerSettings , Properties }
30
29
import scala .tools .nsc .Settings
@@ -33,7 +32,7 @@ import scala.tools.nsc.interpreter.{AbstractOrMissingHandler, ILoop, IMain, JPri
33
32
import scala .tools .nsc .interpreter .{NamedParam , SimpleReader , SplashLoop , SplashReader }
34
33
import scala .tools .nsc .interpreter .StdReplTags .tagOfIMain
35
34
import scala .tools .nsc .util .stringFromStream
36
- import scala .util .Properties .{javaVersion , javaVmName , versionString }
35
+ import scala .util .Properties .{javaVersion , javaVmName , versionNumberString , versionString }
37
36
38
37
/**
39
38
* A Spark-specific interactive shell.
@@ -43,10 +42,32 @@ class SparkILoop(in0: Option[BufferedReader], out: JPrintWriter)
43
42
def this (in0 : BufferedReader , out : JPrintWriter ) = this (Some (in0), out)
44
43
def this () = this (None , new JPrintWriter (Console .out, true ))
45
44
45
+ /**
46
+ * TODO: Remove the following `override` when the support of Scala 2.11 is ended
47
+ * Scala 2.11 has a bug of finding imported types in class constructors, extends clause
48
+ * which is fixed in Scala 2.12 but never be back-ported into Scala 2.11.x.
49
+ * As a result, we copied the fixes into `SparkILoopInterpreter`. See SPARK-22393 for detail.
50
+ */
46
51
override def createInterpreter (): Unit = {
47
- intp = new SparkILoopInterpreter (settings, out)
52
+ if (isScala2_11) {
53
+ if (addedClasspath != " " ) {
54
+ settings.classpath append addedClasspath
55
+ }
56
+ // scalastyle:off classforname
57
+ // Have to use the default classloader to match the one used in
58
+ // `classOf[Settings]` and `classOf[JPrintWriter]`.
59
+ intp = Class .forName(" org.apache.spark.repl.SparkILoopInterpreter" )
60
+ .getDeclaredConstructor(Seq (classOf [Settings ], classOf [JPrintWriter ]): _* )
61
+ .newInstance(Seq (settings, out): _* )
62
+ .asInstanceOf [IMain ]
63
+ // scalastyle:on classforname
64
+ } else {
65
+ super .createInterpreter()
66
+ }
48
67
}
49
68
69
+ private val isScala2_11 = versionNumberString.startsWith(" 2.11" )
70
+
50
71
val initializationCommands : Seq [String ] = Seq (
51
72
"""
52
73
@transient val spark = if (org.apache.spark.repl.Main.sparkSession != null) {
@@ -124,6 +145,26 @@ class SparkILoop(in0: Option[BufferedReader], out: JPrintWriter)
124
145
super .replay()
125
146
}
126
147
148
+ /**
149
+ * TODO: Remove `runClosure` when the support of Scala 2.11 is ended
150
+ */
151
+ private def runClosure (body : => Boolean ): Boolean = {
152
+ if (isScala2_11) {
153
+ // In Scala 2.11, there is a bug that interpret could set the current thread's
154
+ // context classloader, but fails to reset it to its previous state when returning
155
+ // from that method. This is fixed in SI-8521 https://github.com/scala/scala/pull/5657
156
+ // which is never back-ported into Scala 2.11.x. The following is a workaround fix.
157
+ val original = Thread .currentThread().getContextClassLoader
158
+ try {
159
+ body
160
+ } finally {
161
+ Thread .currentThread().setContextClassLoader(original)
162
+ }
163
+ } else {
164
+ body
165
+ }
166
+ }
167
+
127
168
/**
128
169
* The following code is mostly a copy of `process` implementation in `ILoop.scala` in Scala
129
170
*
@@ -138,7 +179,7 @@ class SparkILoop(in0: Option[BufferedReader], out: JPrintWriter)
138
179
* We should remove this duplication once Scala provides a way to load our custom initialization
139
180
* code, and also customize the ordering of printing welcome message.
140
181
*/
141
- override def process (settings : Settings ): Boolean = savingContextLoader {
182
+ override def process (settings : Settings ): Boolean = runClosure {
142
183
143
184
def newReader = in0.fold(chooseReader(settings))(r => SimpleReader (r, out, interactive = true ))
144
185
0 commit comments