From 2c473fc31de5e3862fa67283bcce907e4930a363 Mon Sep 17 00:00:00 2001 From: Ethan Atkins Date: Sat, 1 Feb 2020 14:40:05 -0800 Subject: [PATCH] Improve ClassLoader layering error message When a class on the project classpath is loaded via reflection by one of the parents of the project classloader, sbt run can fail with a mysterious ClassNotFoundException. This is expected behavior but it wasn't previously explained to the user. Ref https://github.com/sbt/sbt/issues/5410. --- run/src/main/scala/sbt/Run.scala | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/run/src/main/scala/sbt/Run.scala b/run/src/main/scala/sbt/Run.scala index 12e1efd01..a51aa3eda 100644 --- a/run/src/main/scala/sbt/Run.scala +++ b/run/src/main/scala/sbt/Run.scala @@ -78,7 +78,22 @@ class Run(private[sbt] val newLoader: Seq[File] => ClassLoader, trapExit: Boolea val main = getMainMethod(mainClass, loader) invokeMain(loader, main, options) } catch { - case e: java.lang.reflect.InvocationTargetException => throw e.getCause + case e: java.lang.reflect.InvocationTargetException => + e.getCause match { + case ex: ClassNotFoundException => + val className = ex.getMessage + try { + loader.loadClass(className) + val msg = + s"$className is on the project classpath but not visible to the ClassLoader " + + "that attempted to load it.\n" + + "See https://www.scala-sbt.org/1.x/docs/In-Process-Classloaders.html for " + + "further information." + log.error(msg) + } catch { case NonFatal(_) => } + throw ex + case ex => throw ex + } } def directExecute(): Try[Unit] = Try(execute()) recover {