From f5fb537c6d565642cd65e0845f93466ddef212d4 Mon Sep 17 00:00:00 2001 From: Eugene Yokota <eed3si9n@gmail.com> Date: Wed, 29 Dec 2021 00:18:51 -0500 Subject: [PATCH 1/2] sbt 1.6.1 --- sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sbt b/sbt index 6d153b3365..07e3c04091 100755 --- a/sbt +++ b/sbt @@ -1,7 +1,7 @@ #!/usr/bin/env bash set +e -declare builtin_sbt_version="1.6.0" +declare builtin_sbt_version="1.6.1" declare -a residual_args declare -a java_args declare -a scalac_args From a549e79c1d2c80a443d544581eb52e4985a909bf Mon Sep 17 00:00:00 2001 From: Eugene Yokota <eed3si9n@gmail.com> Date: Mon, 31 Jan 2022 16:37:38 -0500 Subject: [PATCH 2/2] Throw when test framework cannot be loaded due to MatchError or NoClassDefFoundError Problem ------- In some situations like Dotty Community Build, sbt version is mechanically upgraded on an old commit without humans checking the log. For reasons we're not completely sure (likely change in ClassLoader structure) sbt 1.6.x started to fail to load test frameworks during tests, but since the failure of the test framework loading doesn't fail the task, this silently succeeded the builds. Solution -------- On MatchError and NoClassDefFound Error, rethrow the exception. Note that ClassNotFoundException is considered ok since we have predefined test frameworks listed in sbt, which often are not included in the users' classpath. --- build.sbt | 2 +- .../src/main/scala/sbt/TestFramework.scala | 22 ++++++++++++------- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/build.sbt b/build.sbt index e8c0a5d3b7..edb4d43400 100644 --- a/build.sbt +++ b/build.sbt @@ -10,7 +10,7 @@ import scala.util.Try // ThisBuild settings take lower precedence, // but can be shared across the multi projects. ThisBuild / version := { - val v = "1.6.0-SNAPSHOT" + val v = "1.6.2-SNAPSHOT" nightlyVersion.getOrElse(v) } ThisBuild / version2_13 := "2.0.0-SNAPSHOT" diff --git a/testing/src/main/scala/sbt/TestFramework.scala b/testing/src/main/scala/sbt/TestFramework.scala index d7e057ac56..fe3f761964 100644 --- a/testing/src/main/scala/sbt/TestFramework.scala +++ b/testing/src/main/scala/sbt/TestFramework.scala @@ -49,12 +49,14 @@ final class TestFramework(val implClassNames: String*) extends Serializable { ): Option[Framework] = { def logError(e: Throwable): Option[Framework] = { log.error( - s"Error loading test framework ($e). This usually means that you are" - + " using a layered class loader that cannot reach the sbt.testing.Framework class." - + " The most likely cause is that your project has a runtime dependency on your" - + " test framework, e.g. scalatest. To fix this, you can try to set\n" - + "Test / classLoaderLayeringStrategy := ClassLoaderLayeringStrategy.ScalaLibrary\nor\n" - + "Test / classLoaderLayeringStrategy := ClassLoaderLayeringStrategy.Flat" + s"""Error loading test framework ($e). + |This often means that you are using a layered class loader that cannot reach the sbt.testing.Framework class. + |The most likely cause is that your project has a runtime dependency on your + |test framework, e.g. ScalaTest. To fix this, you can try to set + | + | Test / classLoaderLayeringStrategy := ClassLoaderLayeringStrategy.ScalaLibrary + |or + | Test / classLoaderLayeringStrategy := ClassLoaderLayeringStrategy.Flat""".stripMargin ) None } @@ -66,8 +68,12 @@ final class TestFramework(val implClassNames: String*) extends Serializable { case oldFramework: OldFramework => new FrameworkWrapper(oldFramework) }) } catch { - case e: NoClassDefFoundError => logError(e) - case e: MatchError => logError(e) + case e: NoClassDefFoundError => + logError(e) + throw e + case e: MatchError => + logError(e) + throw e case _: ClassNotFoundException => log.debug("Framework implementation '" + head + "' not present.") createFramework(loader, log, tail)