Skip to content

Commit a34cd7d

Browse files
committed
Give better feedback for classloader failure in staging
1 parent a0a8f0e commit a34cd7d

File tree

2 files changed

+29
-1
lines changed

2 files changed

+29
-1
lines changed

staging/src/scala/quoted/staging/QuoteDriver.scala

+13-1
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,19 @@ private class QuoteDriver(appClassloader: ClassLoader) extends Driver:
5353
val method = clazz.getMethod("apply")
5454
val inst = clazz.getConstructor().newInstance()
5555

56-
method.invoke(inst).asInstanceOf[T]
56+
try method.invoke(inst).asInstanceOf[T]
57+
catch case ex: java.lang.reflect.InvocationTargetException =>
58+
ex.getCause match
59+
case ex: java.lang.NoClassDefFoundError =>
60+
throw new Exception(
61+
s"""`scala.quoted.staging.run` failed to load a class.
62+
|The classloader used for the `staging.Compiler` instance might not be the correct one.
63+
|Make sure that this classloader is the one that loaded the missing class.
64+
|Note that the classloader that loads the standard library might not be the same as
65+
|the one that loaded the application classes.""".stripMargin,
66+
ex)
67+
68+
case _ => throw ex
5769
end match
5870

5971
end run

tests/run-staging/i19170b.scala

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import scala.quoted.*
2+
3+
given staging.Compiler =
4+
staging.Compiler.make(getClass.getClassLoader) // warn: Suspicious top-level unqualified call to getClass
5+
6+
class A(i: Int)
7+
8+
def f(i: Expr[Int])(using Quotes): Expr[A] = { '{ new A($i) } }
9+
10+
@main def Test = {
11+
try
12+
val g: Int => A = staging.run { '{ (i: Int) => ${ f('{i}) } } }
13+
println(g(3))
14+
catch case ex: Exception =>
15+
assert(ex.getMessage().startsWith("`scala.quoted.staging.run` failed to load a class."))
16+
}

0 commit comments

Comments
 (0)