diff --git a/notes/0.13.8/clone-properties-in-junit-tests-listener.markdown b/notes/0.13.8/clone-properties-in-junit-tests-listener.markdown new file mode 100644 index 000000000..ef93007d5 --- /dev/null +++ b/notes/0.13.8/clone-properties-in-junit-tests-listener.markdown @@ -0,0 +1,10 @@ + [@aerskine]: https://github.com/aerskine + [1881]: https://github.com/sbt/sbt/issues/1881 + +### Fixes with compatibility implications + +### Improvements + +### Bug fixes + +- Fixes sporadic ConcurrentModificationException from JUnitXmlTestsListener. [#1881][1881] by [@aerskine][@aerskine] diff --git a/testing/src/main/scala/sbt/JUnitXmlTestsListener.scala b/testing/src/main/scala/sbt/JUnitXmlTestsListener.scala index 2611486ec..2b3d48334 100644 --- a/testing/src/main/scala/sbt/JUnitXmlTestsListener.scala +++ b/testing/src/main/scala/sbt/JUnitXmlTestsListener.scala @@ -2,6 +2,7 @@ package sbt import java.io.{ IOException, StringWriter, PrintWriter, File } import java.net.InetAddress +import java.util.Hashtable import scala.collection.mutable.ListBuffer import scala.util.DynamicVariable @@ -27,7 +28,9 @@ class JUnitXmlTestsListener(val outputDir: String) extends TestsListener { val properties = { - val iter = System.getProperties.entrySet.iterator + // create a clone, defending against [[ConcurrentModificationException]] + val clonedProperties = System.getProperties.clone.asInstanceOf[Hashtable[AnyRef, AnyRef]] + val iter = clonedProperties.entrySet.iterator val props: ListBuffer[XNode] = new ListBuffer() while (iter.hasNext) { val next = iter.next