From 612e64d8e3a821407604f58f1c1532318a6570c2 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Fri, 30 Jun 2017 15:35:56 +0300 Subject: [PATCH] Load module-info.class from multi-release jars' META-INF/versions/ --- .../jvm/compiler/ClasspathRootsResolver.kt | 9 ++++- .../multiReleaseLibrary/library/foo/Foo.java | 3 ++ .../library/module-info.java | 3 ++ .../javaModules/multiReleaseLibrary/main.txt | 1 + .../multiReleaseLibrary/main/module-info.java | 3 ++ .../multiReleaseLibrary/main/usage.kt | 6 ++++ .../AbstractKotlinCompilerIntegrationTest.kt | 4 ++- .../compiler/Java9ModulesIntegrationTest.kt | 33 +++++++++++++++++++ 8 files changed, 60 insertions(+), 2 deletions(-) create mode 100644 compiler/testData/javaModules/multiReleaseLibrary/library/foo/Foo.java create mode 100644 compiler/testData/javaModules/multiReleaseLibrary/library/module-info.java create mode 100644 compiler/testData/javaModules/multiReleaseLibrary/main.txt create mode 100644 compiler/testData/javaModules/multiReleaseLibrary/main/module-info.java create mode 100644 compiler/testData/javaModules/multiReleaseLibrary/main/usage.kt diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/ClasspathRootsResolver.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/ClasspathRootsResolver.kt index f02d9288501..cb7d801a51f 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/ClasspathRootsResolver.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/ClasspathRootsResolver.kt @@ -109,7 +109,10 @@ internal class ClasspathRootsResolver( } private fun modularBinaryRoot(root: VirtualFile, automaticModuleName: () -> String): JavaModule? { - val moduleInfoFile = root.findChild(PsiJavaModule.MODULE_INFO_CLS_FILE) + val moduleInfoFile = + root.findChild(PsiJavaModule.MODULE_INFO_CLS_FILE) + ?: root.takeIf { it.fileSystem.protocol == StandardFileSystems.JAR_PROTOCOL } + ?.findFileByRelativePath(MULTI_RELEASE_MODULE_INFO_CLS_FILE) return if (moduleInfoFile != null) { val moduleInfo = JavaModuleInfo.read(moduleInfoFile) ?: return null JavaModule.Explicit(moduleInfo, root, moduleInfoFile, isBinary = true) @@ -209,4 +212,8 @@ internal class ClasspathRootsResolver( if (file == null) null else CompilerMessageLocation.create(MessageUtil.virtualFileToPath(file)) ) } + + private companion object { + const val MULTI_RELEASE_MODULE_INFO_CLS_FILE = "META-INF/versions/9/${PsiJavaModule.MODULE_INFO_CLS_FILE}" + } } diff --git a/compiler/testData/javaModules/multiReleaseLibrary/library/foo/Foo.java b/compiler/testData/javaModules/multiReleaseLibrary/library/foo/Foo.java new file mode 100644 index 00000000000..7f566bafd45 --- /dev/null +++ b/compiler/testData/javaModules/multiReleaseLibrary/library/foo/Foo.java @@ -0,0 +1,3 @@ +package foo; + +public class Foo {} diff --git a/compiler/testData/javaModules/multiReleaseLibrary/library/module-info.java b/compiler/testData/javaModules/multiReleaseLibrary/library/module-info.java new file mode 100644 index 00000000000..203b1c0c121 --- /dev/null +++ b/compiler/testData/javaModules/multiReleaseLibrary/library/module-info.java @@ -0,0 +1,3 @@ +module library { + exports foo; +} diff --git a/compiler/testData/javaModules/multiReleaseLibrary/main.txt b/compiler/testData/javaModules/multiReleaseLibrary/main.txt new file mode 100644 index 00000000000..d86bac9de59 --- /dev/null +++ b/compiler/testData/javaModules/multiReleaseLibrary/main.txt @@ -0,0 +1 @@ +OK diff --git a/compiler/testData/javaModules/multiReleaseLibrary/main/module-info.java b/compiler/testData/javaModules/multiReleaseLibrary/main/module-info.java new file mode 100644 index 00000000000..e236e735339 --- /dev/null +++ b/compiler/testData/javaModules/multiReleaseLibrary/main/module-info.java @@ -0,0 +1,3 @@ +module main { + requires library; +} diff --git a/compiler/testData/javaModules/multiReleaseLibrary/main/usage.kt b/compiler/testData/javaModules/multiReleaseLibrary/main/usage.kt new file mode 100644 index 00000000000..f5a7ccf69c2 --- /dev/null +++ b/compiler/testData/javaModules/multiReleaseLibrary/main/usage.kt @@ -0,0 +1,6 @@ +import foo.Foo + +fun usage(): String { + val f: Foo = Foo() + return f.toString() +} diff --git a/compiler/tests/org/jetbrains/kotlin/jvm/compiler/AbstractKotlinCompilerIntegrationTest.kt b/compiler/tests/org/jetbrains/kotlin/jvm/compiler/AbstractKotlinCompilerIntegrationTest.kt index 61ea790d369..9271a4a12d2 100644 --- a/compiler/tests/org/jetbrains/kotlin/jvm/compiler/AbstractKotlinCompilerIntegrationTest.kt +++ b/compiler/tests/org/jetbrains/kotlin/jvm/compiler/AbstractKotlinCompilerIntegrationTest.kt @@ -150,6 +150,8 @@ abstract class AbstractKotlinCompilerIntegrationTest : TestCaseWithTmpdir() { companion object { private val KOTLIN_FILES = Pattern.compile(".*\\.kt$") - private val JAVA_FILES = Pattern.compile(".*\\.java$") + + @JvmStatic + protected val JAVA_FILES = Pattern.compile(".*\\.java$")!! } } diff --git a/compiler/tests/org/jetbrains/kotlin/jvm/compiler/Java9ModulesIntegrationTest.kt b/compiler/tests/org/jetbrains/kotlin/jvm/compiler/Java9ModulesIntegrationTest.kt index 6f616406d74..1c00e31e82d 100644 --- a/compiler/tests/org/jetbrains/kotlin/jvm/compiler/Java9ModulesIntegrationTest.kt +++ b/compiler/tests/org/jetbrains/kotlin/jvm/compiler/Java9ModulesIntegrationTest.kt @@ -16,6 +16,7 @@ package org.jetbrains.kotlin.jvm.compiler +import com.intellij.openapi.util.io.FileUtil import org.jetbrains.kotlin.test.KotlinTestUtils import java.io.File @@ -62,6 +63,22 @@ class Java9ModulesIntegrationTest : AbstractKotlinCompilerIntegrationTest() { KotlinTestUtils.assertEqualsToFile(File(testDataDirectory, "$moduleName.txt"), actual) } + private fun createMultiReleaseJar(jdk9Home: File, destination: File, mainRoot: File, java9Root: File): File { + val command = listOf( + File(jdk9Home, "bin/jar").path, + "--create", "--file=$destination", + "-C", mainRoot.path, ".", + "--release", "9", + "-C", java9Root.path, "." + ) + + val process = ProcessBuilder().command(command).inheritIO().start() + process.waitFor() + assertEquals("'jar' did not finish successfully", 0, process.exitValue()) + + return destination + } + fun testSimple() { val a = module("moduleA") module("moduleB", listOf(a)) @@ -149,4 +166,20 @@ class Java9ModulesIntegrationTest : AbstractKotlinCompilerIntegrationTest() { checkKotlinOutput = checkKotlinOutput("moduleB") ) } + + fun testMultiReleaseLibrary() { + val jdk9Home = KotlinTestUtils.getJdk9HomeIfPossible() ?: return + + val librarySrc = FileUtil.findFilesByMask(JAVA_FILES, File(testDataDirectory, "library")) + val libraryOut = File(tmpdir, "out") + KotlinTestUtils.compileJavaFilesExternallyWithJava9(librarySrc, listOf("-d", libraryOut.path)) + + val libraryOut9 = File(tmpdir, "out9") + libraryOut9.mkdirs() + File(libraryOut, "module-info.class").renameTo(File(libraryOut9, "module-info.class")) + + val libraryJar = createMultiReleaseJar(jdk9Home, File(tmpdir, "library.jar"), libraryOut, libraryOut9) + + module("main", listOf(libraryJar)) + } }