Skip to content

Commit 9a7fbfb

Browse files
committed
update scala3-sbt-bridge from 3.0.0-M2 to 3.0.0, fix LinkageError #SCL-18861 fixed
In Scala 3.0.0-RC1 in sbt-bridge they moved to new compiler interface `xsbti.CompilerInterface2`. Before Scala 3.0.0-RC1 `xsbt.CompilerClassLoader` was used. It resolved `xsbti.*` classes (e.g. xsbti.AnalysisCallback) to the classes from the CompileServer classloader (more specifically, they were taken from `zincRepackaged` aka `incremental-compiler.jar`). `compiler-interface.jar` is also included into Scala 3 compiler classpath. But it was simply ignored, because the classes were already loaded by the parent classloader. After Scala 3.0.0-RC1 `sbt.internal.inc.classpath.DualLoader` is used. (see sbt.internal.inc.AnalyzingCompiler.compile, see also sbt.internal.inc.AnalyzingCompiler.createDualLoader) `parentA` loader represents the compiler classloader. Scala3 compiler uses `xsbti.*` classes directly so it so it's loader needs to resolve the those classes. And they should be resolved to the same classes used in the Compile Server. Before this commit, the classes were resolved to the `compiler-interface` jar file in the compile classpath itself. This caused the LinkageError. To avoid those we delegate all `xsbti.*` classes loading to the SCS classlader. Closely related links: - [`[sbt-bridge] Upgrade to CompilerInterface2`](scala/scala3@5185d4d) - [`[sbt-dotty] Use sbt loader as parent of scala instance loader #10541`](scala/scala3#10541)
1 parent be62277 commit 9a7fbfb

File tree

2 files changed

+17
-2
lines changed

2 files changed

+17
-2
lines changed

project/dependencies.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ object Dependencies {
112112
val compilerBridgeSources_2_10 = "org.scala-sbt" % "compiler-bridge_2.10" % zincVersion classifier "sources"
113113
val compilerBridgeSources_2_11 = "org.scala-sbt" % "compiler-bridge_2.11" % zincVersion classifier "sources"
114114
val compilerBridgeSources_2_13 = "org.scala-sbt" % "compiler-bridge_2.13" % zincVersion classifier "sources"
115-
val scala3SbtBridge = "org.scala-lang" % "scala3-sbt-bridge" % "3.0.0-M2"
115+
val scala3SbtBridge = "org.scala-lang" % "scala3-sbt-bridge" % "3.0.0"
116116

117117
// "provided" danger: we statically depend on a single version, but need to support all the version
118118
// some part of our code is now statically dependent on lib classes, another part uses reflections for other versions

scala/compiler-jps/src/org/jetbrains/jps/incremental/scala/local/CompilerFactoryImpl.scala

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,22 @@ object CompilerFactoryImpl {
8080
private def createScalaInstance(jars: CompilerJars) = {
8181
def createClassLoader(paths: Seq[File]) = {
8282
val urls = Path.toURLs(paths)
83-
val newClassloader = new URLClassLoader(urls, ClasspathUtil.rootLoader)
83+
84+
// NOTE: it's required for only for Scala3 compilation, cause they moved to `xsbti.CompilerInterface2`
85+
// We need to use same compile-interface classes in the Scala3 compiler and Scala Compile Server
86+
// (see commit message for the details SCL-18861)
87+
val isXbtiClass = (className: String) => className.startsWith("xsbti.")
88+
val isNotXbtiClass = (className: String) => !isXbtiClass(className)
89+
val delegatingToCompilerInterfaceLoader = new classpath.DualLoader(
90+
classOf[xsbti.AnalysisCallback].getClassLoader, // any class from compiler-interface
91+
isXbtiClass,
92+
_ => false,
93+
ClasspathUtil.rootLoader,
94+
isNotXbtiClass,
95+
_ => true
96+
)
97+
98+
val newClassloader = new URLClassLoader(urls, delegatingToCompilerInterfaceLoader)
8499

85100
classLoadersMap += paths -> newClassloader
86101

0 commit comments

Comments
 (0)