facewindu / sbt-stackoverflow

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Reproducer for issue sbt/sbt#7509

The build contains a failingTask task, which throws a self-referencing exception

lazy val failingTask = taskKey[Unit]("Failing task")

failingTask := {
    val selfReferencingException = new Exception("BOOM self")
    selfReferencingException.initCause(
        new Exception("BOOM cause", selfReferencingException)
    )
    throw selfReferencingException
}

When executing sbt failingTask, the build will throw a java.lang.StackOverflowError Looking at the sbt code, the while loop is protected against self-causation, but not against deeper recursion.

Java itself protects against this when printing a stacktrace with a identity set of already seen Throwable. See Throwable#printStackTrace

// Guard against malicious overrides of Throwable.equals by
// using a Set with identity equality semantics.
Set<Throwable> dejaVu = Collections.newSetFromMap(new IdentityHashMap<Throwable, Boolean>());

...

if (dejaVu.contains(this)) {
  s.println(prefix + caption + "[CIRCULAR REFERENCE: " + this + "]"); // <---- This gets the code out of the recursion
}

About


Languages

Language:Scala 100.0%