diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/java/test/kt33617/MyClass.java b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/java/test/kt33617/MyClass.java new file mode 100644 index 00000000000..9c79ca3a1fe --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/java/test/kt33617/MyClass.java @@ -0,0 +1,9 @@ +/* + * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package test.kt33617; + +public class MyClass { +} diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/KaptIncrementalWithIsolatingApt.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/KaptIncrementalWithIsolatingApt.kt index 359ec0d47a7..54c3c753957 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/KaptIncrementalWithIsolatingApt.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/KaptIncrementalWithIsolatingApt.kt @@ -8,7 +8,9 @@ package org.jetbrains.kotlin.gradle import org.jetbrains.kotlin.gradle.incapt.IncrementalProcessor import org.jetbrains.kotlin.gradle.util.modify import org.junit.Assert.assertEquals +import org.junit.Assume import org.junit.Test +import test.kt33617.MyClass import java.io.File import java.util.zip.ZipEntry import java.util.zip.ZipOutputStream @@ -113,6 +115,46 @@ class KaptIncrementalWithIsolatingApt : KaptIncrementalIT() { assertContains("Incremental annotation processing (apt mode): false") } } + + /** Regression test for https://youtrack.jetbrains.com/issue/KT-33617. */ + @Test + fun testSourcesInCompileClasspathJars() { + val javaHome = File(System.getProperty("jdk9Home")!!) + Assume.assumeTrue("JDK 9 isn't available", javaHome.isDirectory) + val options = defaultBuildOptions().copy(javaHome = javaHome) + + val project = getProject() + // create jar with .class and .java file for the same type + ZipOutputStream(project.projectDir.resolve("lib-with-sources.jar").outputStream()).use { + it.putNextEntry(ZipEntry("test/kt33617/MyClass.class")) + MyClass::class.java.classLoader.getResourceAsStream("test/kt33617/MyClass.class").use { input -> + it.write(input!!.readBytes()) + } + it.closeEntry() + + it.putNextEntry(ZipEntry("test/kt33617/MyClass.java")) + it.write( + """ + package test.kt33617; + public class MyClass {} + """.trimIndent().toByteArray(Charsets.UTF_8) + ) + it.closeEntry() + } + project.gradleBuildScript().appendText( + """ + + dependencies { + implementation files('lib-with-sources.jar') + } + """.trimIndent() + ) + project.projectFile("useB.kt").modify { current -> "$current\nfun otherFunction(param: test.kt33617.MyClass) {}" } + + project.build("clean", "kaptKotlin", options = options) { + assertSuccessful() + } + } } private const val patternApt = "Processing java sources with annotation processors:" diff --git a/plugins/kapt3/kapt3-base/src/org/jetbrains/kotlin/kapt3/base/incremental/classStructureCache.kt b/plugins/kapt3/kapt3-base/src/org/jetbrains/kotlin/kapt3/base/incremental/classStructureCache.kt index ae89a466d28..374db2302af 100644 --- a/plugins/kapt3/kapt3-base/src/org/jetbrains/kotlin/kapt3/base/incremental/classStructureCache.kt +++ b/plugins/kapt3/kapt3-base/src/org/jetbrains/kotlin/kapt3/base/incremental/classStructureCache.kt @@ -9,6 +9,7 @@ import java.io.File import java.io.ObjectInputStream import java.io.ObjectOutputStream import java.io.Serializable +import java.lang.IllegalArgumentException import java.net.URI import java.util.regex.Pattern @@ -73,7 +74,23 @@ class JavaClassCache() : Serializable { output.writeObject(generatedTypes) } - fun isAlreadyProcessed(sourceFile: URI) = sourceCache.containsKey(sourceFile) || generatedTypes.containsKey(File(sourceFile)) + fun isAlreadyProcessed(sourceFile: URI): Boolean { + if (!sourceFile.isAbsolute) { + // we never want to process non-absolute URIs, see https://youtrack.jetbrains.com/issue/KT-33617 + return true + } + if (sourceFile.isOpaque) { + // we never want to process non-hierarchical URIs, https://youtrack.jetbrains.com/issue/KT-33617 + return true + } + return try { + val fileFromUri = File(sourceFile) + sourceCache.containsKey(sourceFile) || generatedTypes.containsKey(fileFromUri) + } catch (e: IllegalArgumentException) { + // unable to create File instance, avoid processing these files + true + } + } /** Used for testing only. */ internal fun getStructure(sourceFile: File) = sourceCache[sourceFile.toURI()]