From 66d344975b38e846105e4431babccde1843824fb Mon Sep 17 00:00:00 2001 From: "sebastian.sellmair" Date: Wed, 15 Jun 2022 14:52:48 +0200 Subject: [PATCH] [Gradle] KotlinToolRunner: Capture `System.getProperties()` as List This is done to avoid a potential `ConcurrentModificationException`: ``` Caused by: java.util.ConcurrentModificationException at java.util.Hashtable$Enumerator.next(Hashtable.java:1387) at org.gradle.internal.classpath.Instrumented$DecoratingEntrySet$1.computeNext(Instrumented.java:349) at org.gradle.internal.classpath.Instrumented$DecoratingEntrySet$1.computeNext(Instrumented.java:343) at com.google.common.collect.AbstractIterator.tryToComputeNext(AbstractIterator.java:141) at com.google.common.collect.AbstractIterator.hasNext(AbstractIterator.java:136) at kotlin.sequences.TransformingSequence$iterator$1.hasNext(Sequences.kt:176) at kotlin.sequences.FilteringSequence$iterator$1.calcNext(Sequences.kt:131) at kotlin.sequences.FilteringSequence$iterator$1.hasNext(Sequences.kt:156) at kotlin.collections.MapsKt__MapsKt.putAll(Maps.kt:419) at kotlin.collections.MapsKt__MapsKt.toMap(Maps.kt:587) at kotlin.collections.MapsKt__MapsKt.toMap(Maps.kt:581) at org.jetbrains.kotlin.compilerRunner.KotlinToolRunner.runViaExec(KotlinToolRunner.kt:95) at org.jetbrains.kotlin.compilerRunner.KotlinToolRunner.run(KotlinToolRunner.kt:85) ``` --- .../kotlin/compilerRunner/KotlinToolRunner.kt | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/KotlinToolRunner.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/KotlinToolRunner.kt index c2dde3adb6f..cea60c2f923 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/KotlinToolRunner.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/KotlinToolRunner.kt @@ -12,6 +12,7 @@ import org.jetbrains.kotlin.konan.target.HostManager import java.io.File import java.lang.reflect.InvocationTargetException import java.net.URLClassLoader +import java.util.* import java.util.concurrent.ConcurrentHashMap // Note: this class is public because it is used in the K/N build infrastructure. @@ -88,7 +89,10 @@ abstract class KotlinToolRunner( private fun runViaExec(args: List) { val transformedArgs = transformArgs(args) val classpath = project.files(classpath) - val systemProperties = System.getProperties().asSequence() + val systemProperties = System.getProperties() + /* Capture 'System.getProperties()' as List to avoid potential 'ConcurrentModificationException' */ + .toListSynchronized() + .asSequence() .map { (k, v) -> k.toString() to v.toString() } .filter { (k, _) -> k !in execSystemPropertiesBlacklist } .escapeQuotesForWindows() @@ -173,5 +177,10 @@ abstract class KotlinToolRunner( any { it == '"' || it.isWhitespace() } -> '"' + escapeStringCharacters(this) + '"' else -> this } + + /** + * Safely enter the [Properties] monitor and capture the current values + */ + private fun Properties.toListSynchronized(): List> = synchronized(this) { toList() } } }