Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 50c7e5e

Browse files
jbarr21tschuchortdev
authored andcommitted
Fix decoding of classloader resources
* Fix decoding of classloader resources * Document internal method * Fix paths on Windows (cherry picked from commit 468101f)
1 parent 29a1e48 commit 50c7e5e

File tree

2 files changed

+38
-11
lines changed

2 files changed

+38
-11
lines changed

‎core/src/main/kotlin/com/tschuchort/compiletesting/AbstractKotlinCompilation.kt

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import java.io.File
2121
import java.io.OutputStream
2222
import java.io.PrintStream
2323
import java.net.URI
24+
import java.net.URL
2425
import java.nio.file.Files
2526
import java.nio.file.Path
2627
import java.nio.file.Paths
@@ -62,8 +63,6 @@ abstract class AbstractKotlinCompilation<A : CommonCompilerArguments> internal c
6263
)
6364
var compilerPlugins: List<ComponentRegistrar> = emptyList()
6465

65-
66-
6766
/**
6867
* Legacy compiler plugins that should be added to the compilation.
6968
* This option will be removed in the future; you should migrate to [CompilerPluginRegistrar].
@@ -273,23 +272,26 @@ abstract class AbstractKotlinCompilation<A : CommonCompilerArguments> internal c
273272
}
274273

275274
protected fun getResourcesPath(): String {
276-
val resourceName = "META-INF/services/org.jetbrains.kotlin.compiler.plugin.CompilerPluginRegistrar"
277275
return this::class.java.classLoader.getResources(resourceName)
278276
.asSequence()
279-
.mapNotNull { url ->
280-
val uri = URI.create(url.toString().removeSuffix("/$resourceName"))
281-
when (uri.scheme) {
282-
"jar" -> Paths.get(URI.create(uri.rawSchemeSpecificPart.removeSuffix("!")))
283-
"file" -> Paths.get(uri)
284-
else -> return@mapNotNull null
285-
}.toAbsolutePath()
286-
}
277+
.mapNotNull { url -> urlToResourcePath(url) }
287278
.find { resourcesPath ->
288279
ServiceLoaderLite.findImplementations(CompilerPluginRegistrar::class.java, listOf(resourcesPath.toFile()))
289280
.any { implementation -> implementation == MainComponentAndPluginRegistrar::class.java.name }
290281
}?.toString() ?: throw AssertionError("Could not get path to CompilerPluginRegistrar service from META-INF")
291282
}
292283

284+
/** Maps a URL resource for a class from a JAR or file to an absolute Path on disk */
285+
internal fun urlToResourcePath(url: URL): Path? {
286+
val uri = url.toURI()
287+
val uriPath = when (uri.scheme) {
288+
"jar" -> uri.rawSchemeSpecificPart.removeSuffix("!/$resourceName")
289+
"file" -> uri.toString().removeSuffix("/$resourceName")
290+
else -> return null
291+
}
292+
return Paths.get(URI.create(uriPath)).toAbsolutePath()
293+
}
294+
293295
/** Searches compiler log for known errors that are hard to debug for the user */
294296
protected fun searchSystemOutForKnownErrors(compilerSystemOut: String) {
295297
if (compilerSystemOut.contains("No enum constant com.sun.tools.javac.main.Option.BOOT_CLASS_PATH")) {
@@ -340,8 +342,11 @@ abstract class AbstractKotlinCompilation<A : CommonCompilerArguments> internal c
340342
protected fun error(s: String) = internalMessageStream.println("error: $s")
341343

342344
internal val internalMessageStreamAccess: PrintStream get() = internalMessageStream
345+
346+
internal val resourceName = "META-INF/services/org.jetbrains.kotlin.compiler.plugin.CompilerPluginRegistrar"
343347
}
344348

349+
@ExperimentalCompilerApi
345350
internal fun convertKotlinExitCode(code: ExitCode) = when(code) {
346351
ExitCode.OK -> KotlinCompilation.ExitCode.OK
347352
ExitCode.INTERNAL_ERROR -> KotlinCompilation.ExitCode.INTERNAL_ERROR

‎core/src/test/kotlin/com/tschuchort/compiletesting/CompilerPluginsTest.kt

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import org.junit.Assert
66
import org.junit.Ignore
77
import org.junit.Test
88
import org.mockito.Mockito
9+
import java.net.URL
910
import javax.annotation.processing.AbstractProcessor
1011
import javax.annotation.processing.RoundEnvironment
1112
import javax.lang.model.element.TypeElement
@@ -105,4 +106,25 @@ class CompilerPluginsTest {
105106
fakePlugin.assertRegistered()
106107
Assertions.assertThat(result.exitCode).isEqualTo(KotlinCompilation.ExitCode.OK)
107108
}
109+
110+
@Test
111+
fun `convert jar url resource to path without decoding encoded path`() {
112+
// path on disk has "url%3Aport" path segment, but it's encoded from classLoader.getResources()
113+
val absolutePath = "jar:file:/path/to/jar/url%253Aport/core-0.4.0.jar!" +
114+
"/META-INF/services/org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar"
115+
val resultPath = KotlinCompilation().urlToResourcePath(URL(absolutePath)).toString()
116+
Assertions.assertThat(resultPath.contains("url:")).isFalse()
117+
Assertions.assertThat(resultPath.contains("url%25")).isFalse()
118+
Assertions.assertThat(resultPath.contains("url%3A")).isTrue()
119+
}
120+
121+
@Test
122+
fun `convert file url resource to path without decoding`() {
123+
// path on disk has "repos%3Aoss" path segment, but it's encoded from classLoader.getResources()
124+
val absolutePath = "file:/Users/user/repos%253Aoss/kotlin-compile-testing/core/build/resources/main"
125+
val resultPath = KotlinCompilation().urlToResourcePath(URL(absolutePath)).toString()
126+
Assertions.assertThat(resultPath.contains("repos:")).isFalse()
127+
Assertions.assertThat(resultPath.contains("repos%25")).isFalse()
128+
Assertions.assertThat(resultPath.contains("repos%3A")).isTrue()
129+
}
108130
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /