Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Presentation Compiler is now loaded with correct classloader #7002

Merged

Conversation

rochala
Copy link
Collaborator

@rochala rochala commented Dec 3, 2024

Fixes #6494
Fixes scala/scala3#20560

We've found that classloader used to load presentation compiler is defined as follows:

package scala.meta.internal.metals

/**
 * ClassLoader that is used to reflectively invoke presentation compiler APIs.
 *
 * The presentation compiler APIs are compiled against exact Scala versions of the compiler
 * while Metals only runs in a single Scala version. In order to communicate between Metals and the
 * reflectively loaded compiler, this classloader shares a subset of Java classes that appear in
 * method signatures of the `PresentationCompiler` class.
 */
class PresentationCompilerClassLoader(parent: ClassLoader)
    extends ClassLoader(null) {
  override def findClass(name: String): Class[_] = {
    val isShared =
      name.startsWith("org.eclipse.lsp4j") ||
        name.startsWith("com.google.gson") ||
        name.startsWith("scala.meta.pc") ||
        name.startsWith("javax")
    if (isShared) {
      parent.loadClass(name)
    } else {
      throw new ClassNotFoundException(name)
    }
  }
}

and it is used as a parent classloader:

  private def newPresentationCompilerClassLoader(
      mtags: MtagsBinaries.Artifacts
  ): URLClassLoader = {
    val allJars = mtags.jars.iterator
    val allURLs = allJars.map(_.toUri.toURL).toArray
    // Share classloader for a subset of types.
    val parent =
      new PresentationCompilerClassLoader(this.getClass.getClassLoader)
    new URLClassLoader(allURLs, parent)
  }

This approach won't work on java 9+
More information here: https://github.com/scala/scala3/pull/11658/files

Copy link
Contributor

@tgodzik tgodzik left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great catch!

@tgodzik tgodzik merged commit c291bd2 into scalameta:main Dec 3, 2024
22 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
2 participants