Skip to content

Commit 89c355a

Browse files
committed
[KYUUBI #3627] Support vanilla Jetty for Spark packaged by sbt
### _Why are the changes needed?_ Fix #3627. ### _How was this patch tested?_ - [ ] Add some test cases that check the changes thoroughly including negative and positive cases if possible - [x] Add screenshots for manual tests if appropriate manual test, and the class not found error is gone. - [ ] [Run test](https://kyuubi.apache.org/docs/latest/develop_tools/testing.html#running-tests) locally before make a pull request Closes #3630 from pan3793/jetty. Closes #3627 bf9e4f9 [Cheng Pan] private f6c496f [Cheng Pan] nit 25a7c8c [Cheng Pan] [KYUUBI #3627] Support vanilla Jetty for Spark packaged by sbt Authored-by: Cheng Pan <chengpan@apache.org> Signed-off-by: Cheng Pan <chengpan@apache.org> (cherry picked from commit 33c573c) Signed-off-by: Cheng Pan <chengpan@apache.org>
1 parent 9d7f30e commit 89c355a

File tree

1 file changed

+26
-8
lines changed
  • externals/kyuubi-spark-sql-engine/src/main/scala/org/apache/spark/ui

1 file changed

+26
-8
lines changed

externals/kyuubi-spark-sql-engine/src/main/scala/org/apache/spark/ui/EngineTab.scala

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import org.apache.kyuubi.config.KyuubiConf
2626
import org.apache.kyuubi.engine.spark.SparkSQLEngine
2727
import org.apache.kyuubi.engine.spark.events.EngineEventsStore
2828
import org.apache.kyuubi.service.ServiceState
29+
import org.apache.kyuubi.util.ClassUtils
2930

3031
/**
3132
* Note that [[SparkUITab]] is private for Spark
@@ -61,26 +62,43 @@ case class EngineTab(
6162

6263
sparkUI.foreach { ui =>
6364
try {
64-
// Spark shade the jetty package so here we use reflect
65+
// Spark shade the jetty package so here we use reflection
66+
val sparkServletContextHandlerClz = loadSparkServletContextHandler
6567
Class.forName("org.apache.spark.ui.SparkUI")
66-
.getMethod("attachHandler", classOf[org.sparkproject.jetty.servlet.ServletContextHandler])
68+
.getMethod("attachHandler", sparkServletContextHandlerClz)
6769
.invoke(
6870
ui,
6971
Class.forName("org.apache.spark.ui.JettyUtils")
7072
.getMethod(
7173
"createRedirectHandler",
7274
classOf[String],
7375
classOf[String],
74-
classOf[(HttpServletRequest) => Unit],
76+
classOf[HttpServletRequest => Unit],
7577
classOf[String],
7678
classOf[scala.collection.immutable.Set[String]])
7779
.invoke(null, "/kyuubi/stop", "/kyuubi", handleKillRequest _, "", Set("GET", "POST")))
7880
} catch {
79-
case NonFatal(e) =>
80-
warn(
81-
"Failed to attach handler using SparkUI, please check the Spark version. " +
82-
s"So the config '${KyuubiConf.ENGINE_UI_STOP_ENABLED.key}' does not work.",
83-
e)
81+
case NonFatal(cause) => reportInstallError(cause)
82+
case cause: NoClassDefFoundError => reportInstallError(cause)
83+
}
84+
}
85+
86+
private def reportInstallError(cause: Throwable): Unit = {
87+
warn(
88+
"Failed to attach handler using SparkUI, please check the Spark version. " +
89+
s"So the config '${KyuubiConf.ENGINE_UI_STOP_ENABLED.key}' does not work.",
90+
cause)
91+
}
92+
93+
private def loadSparkServletContextHandler: Class[_] = {
94+
// [KYUUBI #3627]: the official spark release uses the shaded and relocated jetty classes,
95+
// but if use sbt to build for testing, e.g. docker image, it still uses vanilla jetty classes.
96+
val shaded = "org.sparkproject.jetty.servlet.ServletContextHandler"
97+
val vanilla = "org.eclipse.jetty.servlet.ServletContextHandler"
98+
if (ClassUtils.classIsLoadable(shaded)) {
99+
Class.forName(shaded)
100+
} else {
101+
Class.forName(vanilla)
84102
}
85103
}
86104

0 commit comments

Comments
 (0)