diff --git a/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/config/Configurations.kt b/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/config/Configurations.kt index 6a3a51d3c3c1..c0723e7afdb4 100644 --- a/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/config/Configurations.kt +++ b/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/config/Configurations.kt @@ -2,6 +2,7 @@ package io.gitlab.arturbosch.detekt.core.config import io.github.detekt.tooling.api.spec.ConfigSpec import io.github.detekt.tooling.api.spec.ProcessingSpec +import io.github.detekt.tooling.internal.openSafeStream import io.gitlab.arturbosch.detekt.api.Config import java.net.URI import java.net.URL @@ -29,10 +30,10 @@ internal fun ProcessingSpec.loadConfiguration(): Config = with(configSpec) { private fun parseResourceConfig(urls: Collection): Config = if (urls.size == 1) { - YamlConfig.loadResource(urls.first()) + YamlConfig.load(urls.first().openSafeStream().reader()) } else { urls.asSequence() - .map { YamlConfig.loadResource(it) } + .map { YamlConfig.load(it.openSafeStream().reader()) } .reduce { composite, config -> CompositeConfig(config, composite) } } diff --git a/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/config/DefaultConfig.kt b/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/config/DefaultConfig.kt index 0a8cdfc03401..b020d40a92f7 100644 --- a/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/config/DefaultConfig.kt +++ b/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/config/DefaultConfig.kt @@ -1,5 +1,6 @@ package io.gitlab.arturbosch.detekt.core.config +import io.github.detekt.tooling.internal.getSafeResourceAsStream import io.gitlab.arturbosch.detekt.api.Config internal object DefaultConfig { @@ -7,7 +8,7 @@ internal object DefaultConfig { const val RESOURCE_NAME = "default-detekt-config.yml" fun newInstance(): Config { - val configUrl = javaClass.getResource("/$RESOURCE_NAME")!! - return YamlConfig.loadResource(configUrl) + val configReader = javaClass.getSafeResourceAsStream("/$RESOURCE_NAME")!!.reader() + return YamlConfig.load(configReader) } } diff --git a/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/config/YamlConfig.kt b/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/config/YamlConfig.kt index 488d706f84f2..d595677ff271 100644 --- a/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/config/YamlConfig.kt +++ b/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/config/YamlConfig.kt @@ -58,21 +58,6 @@ class YamlConfig internal constructor( }.reader() ) - /** - * Factory method to load a yaml configuration from a URL. - */ - fun loadResource(url: URL): Config = load( - url.openConnection() - /* - * Due to https://bugs.openjdk.java.net/browse/JDK-6947916 and https://bugs.openjdk.java.net/browse/JDK-8155607, - * it is necessary to disallow caches to maintain stability on JDK 8. Otherwise, simultaneous invocations of - * Detekt in the same VM can fail spuriously. A similar bug is referenced in - * https://github.com/detekt/detekt/issues/3396. The performance regression is likely unnoticeable. - */ - .apply { if (System.getProperty("java.specification.version") == "1.8") useCaches = false } - .getInputStream().reader() - ) - /** * Constructs a [YamlConfig] from any [Reader]. * diff --git a/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/tooling/DefaultConfigProvider.kt b/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/tooling/DefaultConfigProvider.kt index 91107b0dc14f..63de133ee3d3 100644 --- a/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/tooling/DefaultConfigProvider.kt +++ b/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/tooling/DefaultConfigProvider.kt @@ -1,6 +1,7 @@ package io.gitlab.arturbosch.detekt.core.tooling import io.github.detekt.tooling.api.DefaultConfigurationProvider +import io.github.detekt.tooling.internal.openSafeStream import io.gitlab.arturbosch.detekt.api.Config import io.gitlab.arturbosch.detekt.core.config.DefaultConfig import java.nio.file.Files @@ -13,6 +14,6 @@ class DefaultConfigProvider : DefaultConfigurationProvider { override fun copy(targetLocation: Path) { val configUrl = javaClass.getResource("/${DefaultConfig.RESOURCE_NAME}")!! - Files.copy(configUrl.openStream(), targetLocation, StandardCopyOption.REPLACE_EXISTING) + Files.copy(configUrl.openSafeStream(), targetLocation, StandardCopyOption.REPLACE_EXISTING) } } diff --git a/detekt-core/src/test/kotlin/io/gitlab/arturbosch/detekt/core/config/YamlConfigSpec.kt b/detekt-core/src/test/kotlin/io/gitlab/arturbosch/detekt/core/config/YamlConfigSpec.kt index 29960659f068..67007d8f8202 100644 --- a/detekt-core/src/test/kotlin/io/gitlab/arturbosch/detekt/core/config/YamlConfigSpec.kt +++ b/detekt-core/src/test/kotlin/io/gitlab/arturbosch/detekt/core/config/YamlConfigSpec.kt @@ -3,6 +3,7 @@ package io.gitlab.arturbosch.detekt.core.config import io.github.detekt.test.utils.resourceAsPath +import io.github.detekt.tooling.internal.getSafeResourceAsStream import io.gitlab.arturbosch.detekt.api.Config import io.gitlab.arturbosch.detekt.test.yamlConfig import io.gitlab.arturbosch.detekt.test.yamlConfigFromContent @@ -58,11 +59,11 @@ class YamlConfigSpec : Spek({ describe("loading empty configurations") { it("empty yaml file is equivalent to empty config") { - YamlConfig.loadResource(javaClass.getResource("/empty.yml")) + YamlConfig.load(javaClass.getSafeResourceAsStream("/empty.yml")!!.reader()) } it("single item in yaml file is valid") { - YamlConfig.loadResource(javaClass.getResource("/oneitem.yml")) + YamlConfig.load(javaClass.getSafeResourceAsStream("/oneitem.yml")!!.reader()) } } diff --git a/detekt-test/src/main/kotlin/io/gitlab/arturbosch/detekt/test/Resources.kt b/detekt-test/src/main/kotlin/io/gitlab/arturbosch/detekt/test/Resources.kt index 5571ed0938c7..8a7559526446 100644 --- a/detekt-test/src/main/kotlin/io/gitlab/arturbosch/detekt/test/Resources.kt +++ b/detekt-test/src/main/kotlin/io/gitlab/arturbosch/detekt/test/Resources.kt @@ -5,7 +5,7 @@ import io.gitlab.arturbosch.detekt.api.Config import io.gitlab.arturbosch.detekt.core.config.YamlConfig import java.io.StringReader -fun yamlConfig(name: String) = YamlConfig.loadResource(resource(name).toURL()) +fun yamlConfig(name: String) = YamlConfig.load(resource(name).toURL().openStream().reader()) fun yamlConfigFromContent(content: String): Config = YamlConfig.load(StringReader(content.trimIndent())) diff --git a/detekt-tooling/src/main/kotlin/io/github/detekt/tooling/internal/Resources.kt b/detekt-tooling/src/main/kotlin/io/github/detekt/tooling/internal/Resources.kt new file mode 100644 index 000000000000..80a8d8a0e5ff --- /dev/null +++ b/detekt-tooling/src/main/kotlin/io/github/detekt/tooling/internal/Resources.kt @@ -0,0 +1,20 @@ +package io.github.detekt.tooling.internal + +import java.io.InputStream +import java.net.URL + +fun URL.openSafeStream(): InputStream { + return openConnection() + /* + * Due to https://bugs.openjdk.java.net/browse/JDK-6947916 and https://bugs.openjdk.java.net/browse/JDK-8155607, + * it is necessary to disallow caches to maintain stability on JDK 8. Otherwise, simultaneous invocations of + * Detekt in the same VM can fail spuriously. A similar bug is referenced in + * https://github.com/detekt/detekt/issues/3396. The performance regression is likely unnoticeable. + */ + .apply { if (System.getProperty("java.specification.version") == "1.8") useCaches = false } + .getInputStream() +} + +fun Class.getSafeResourceAsStream(name: String): InputStream? { + return getResource(name)?.openSafeStream() +}