diff --git a/core/src/main/kotlin/com/tschuchort/compiletesting/AbstractKotlinCompilation.kt b/core/src/main/kotlin/com/tschuchort/compiletesting/AbstractKotlinCompilation.kt
index 009591d1..e881800d 100644
--- a/core/src/main/kotlin/com/tschuchort/compiletesting/AbstractKotlinCompilation.kt
+++ b/core/src/main/kotlin/com/tschuchort/compiletesting/AbstractKotlinCompilation.kt
@@ -20,7 +20,9 @@ import java.io.File
import java.io.OutputStream
import java.io.PrintStream
import java.net.URI
+import java.net.URL
import java.nio.file.Files
+import java.nio.file.Path
import java.nio.file.Paths
/**
@@ -239,23 +241,26 @@ abstract class AbstractKotlinCompilation internal c
}
protected fun getResourcesPath(): String {
- val resourceName = "META-INF/services/org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar"
return this::class.java.classLoader.getResources(resourceName)
.asSequence()
- .mapNotNull { url ->
- val uri = URI.create(url.toString().removeSuffix("/$resourceName"))
- when (uri.scheme) {
- "jar" -> Paths.get(URI.create(uri.schemeSpecificPart.removeSuffix("!")))
- "file" -> Paths.get(uri)
- else -> return@mapNotNull null
- }.toAbsolutePath()
- }
+ .mapNotNull { url -> urlToResourcePath(url) }
.find { resourcesPath ->
ServiceLoaderLite.findImplementations(ComponentRegistrar::class.java, listOf(resourcesPath.toFile()))
.any { implementation -> implementation == MainComponentRegistrar::class.java.name }
}?.toString() ?: throw AssertionError("Could not get path to ComponentRegistrar service from META-INF")
}
+ /** Maps a URL resource for a class from a JAR or file to an absolute Path on disk */
+ internal fun urlToResourcePath(url: URL): Path? {
+ val uri = url.toURI()
+ val uriPath = when (uri.scheme) {
+ "jar" -> uri.rawSchemeSpecificPart.removeSuffix("!/$resourceName")
+ "file" -> uri.toString().removeSuffix("/$resourceName")
+ else -> return null
+ }
+ return Paths.get(URI.create(uriPath)).toAbsolutePath()
+ }
+
/** Searches compiler log for known errors that are hard to debug for the user */
protected fun searchSystemOutForKnownErrors(compilerSystemOut: String) {
if (compilerSystemOut.contains("No enum constant com.sun.tools.javac.main.Option.BOOT_CLASS_PATH")) {
@@ -306,6 +311,8 @@ abstract class AbstractKotlinCompilation internal c
protected fun error(s: String) = internalMessageStream.println("error: $s")
internal val internalMessageStreamAccess: PrintStream get() = internalMessageStream
+
+ private val resourceName = "META-INF/services/org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar"
}
@ExperimentalCompilerApi
diff --git a/core/src/test/kotlin/com/tschuchort/compiletesting/CompilerPluginsTest.kt b/core/src/test/kotlin/com/tschuchort/compiletesting/CompilerPluginsTest.kt
index 160d572a..a8964135 100644
--- a/core/src/test/kotlin/com/tschuchort/compiletesting/CompilerPluginsTest.kt
+++ b/core/src/test/kotlin/com/tschuchort/compiletesting/CompilerPluginsTest.kt
@@ -8,6 +8,7 @@ import org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar
import org.junit.Assert
import org.junit.Test
import org.mockito.Mockito
+import java.net.URL
import javax.annotation.processing.AbstractProcessor
import javax.annotation.processing.RoundEnvironment
import javax.lang.model.element.TypeElement
@@ -71,5 +72,26 @@ class CompilerPluginsTest {
assertThat(result.exitCode).isEqualTo(KotlinCompilation.ExitCode.OK)
}
+
+ @Test
+ fun `convert jar url resource to path without decoding encoded path`() {
+ // path on disk has "url%3Aport" path segment, but it's encoded from classLoader.getResources()
+ val absolutePath = "jar:file:/path/to/jar/url%253Aport/core-0.4.0.jar!" +
+ "/META-INF/services/org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar"
+ val resultPath = KotlinCompilation().urlToResourcePath(URL(absolutePath)).toString()
+ assertThat(resultPath.contains("url:")).isFalse()
+ assertThat(resultPath.contains("url%25")).isFalse()
+ assertThat(resultPath.contains("url%3A")).isTrue()
+ }
+
+ @Test
+ fun `convert file url resource to path without decoding`() {
+ // path on disk has "repos%3Aoss" path segment, but it's encoded from classLoader.getResources()
+ val absolutePath = "file:/Users/user/repos%253Aoss/kotlin-compile-testing/core/build/resources/main"
+ val resultPath = KotlinCompilation().urlToResourcePath(URL(absolutePath)).toString()
+ assertThat(resultPath.contains("repos:")).isFalse()
+ assertThat(resultPath.contains("repos%25")).isFalse()
+ assertThat(resultPath.contains("repos%3A")).isTrue()
+ }
}