Skip to content

Commit

Permalink
Give better feedback for classloader failure in staging
Browse files Browse the repository at this point in the history
[Cherry-picked a34cd7d]
  • Loading branch information
nicolasstucki authored and WojciechMazur committed Jun 27, 2024
1 parent e9f2ab0 commit fb8f8df
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 1 deletion.
14 changes: 13 additions & 1 deletion staging/src/scala/quoted/staging/QuoteDriver.scala
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,19 @@ private class QuoteDriver(appClassloader: ClassLoader) extends Driver:
val method = clazz.getMethod("apply")
val inst = clazz.getConstructor().newInstance()

method.invoke(inst).asInstanceOf[T]
try method.invoke(inst).asInstanceOf[T]
catch case ex: java.lang.reflect.InvocationTargetException =>
ex.getCause match
case ex: java.lang.NoClassDefFoundError =>
throw new Exception(
s"""`scala.quoted.staging.run` failed to load a class.
|The classloader used for the `staging.Compiler` instance might not be the correct one.
|Make sure that this classloader is the one that loaded the missing class.
|Note that the classloader that loads the standard library might not be the same as
|the one that loaded the application classes.""".stripMargin,
ex)

case _ => throw ex
end match

end run
Expand Down
16 changes: 16 additions & 0 deletions tests/run-staging/i19170b.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import scala.quoted.*

given staging.Compiler =
staging.Compiler.make(getClass.getClassLoader) // warn: Suspicious top-level unqualified call to getClass

class A(i: Int)

def f(i: Expr[Int])(using Quotes): Expr[A] = { '{ new A($i) } }

@main def Test = {
try
val g: Int => A = staging.run { '{ (i: Int) => ${ f('{i}) } } }
println(g(3))
catch case ex: Exception =>
assert(ex.getMessage().startsWith("`scala.quoted.staging.run` failed to load a class."))
}

0 comments on commit fb8f8df

Please sign in to comment.