diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/CompileEnvironmentUtil.java b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/CompileEnvironmentUtil.java index bc73eeeb1b9..bf145a2e193 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/CompileEnvironmentUtil.java +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/CompileEnvironmentUtil.java @@ -19,6 +19,7 @@ package org.jetbrains.kotlin.cli.jvm.compiler; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.io.FileUtilRt; import kotlin.io.FilesKt; +import kotlin.text.StringsKt; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.kotlin.backend.common.output.OutputFile; @@ -131,6 +132,9 @@ public class CompileEnvironmentUtil { if (e == null) { break; } + if (StringsKt.substringAfterLast(e.getName(), "/", e.getName()).equals("module-info.class")) { + continue; + } if (resetJarTimestamps) { e.setTime(DOS_EPOCH); } diff --git a/compiler/tests/org/jetbrains/kotlin/cli/DeterministicOutputTest.kt b/compiler/tests/org/jetbrains/kotlin/cli/JarOutputTest.kt similarity index 73% rename from compiler/tests/org/jetbrains/kotlin/cli/DeterministicOutputTest.kt rename to compiler/tests/org/jetbrains/kotlin/cli/JarOutputTest.kt index 4ba2a4cf8c3..f32c85e8274 100644 --- a/compiler/tests/org/jetbrains/kotlin/cli/DeterministicOutputTest.kt +++ b/compiler/tests/org/jetbrains/kotlin/cli/JarOutputTest.kt @@ -17,16 +17,14 @@ package org.jetbrains.kotlin.cli import java.io.File -import java.io.FileInputStream -import java.util.jar.JarInputStream -import java.util.zip.ZipEntry import kotlin.test.assertEquals import kotlin.test.assertNotEquals import org.jetbrains.kotlin.cli.jvm.K2JVMCompiler import org.jetbrains.kotlin.cli.jvm.compiler.CompileEnvironmentUtil.DOS_EPOCH import org.jetbrains.kotlin.test.TestCaseWithTmpdir +import java.util.jar.JarFile -class DeterministicOutputTest : TestCaseWithTmpdir() { +class JarOutputTest : TestCaseWithTmpdir() { fun testDeterministicOutput() { val fooKt = tmpdir.resolve("foo.kt").also { @@ -63,21 +61,40 @@ class DeterministicOutputTest : TestCaseWithTmpdir() { assertNoTimestampsAreReset(jar) } + /** + * KT-44078 + */ + fun testNoModuleInfoClass() { + val fooKt = tmpdir.resolve("foo.kt").also { + it.writeText("class Foo") + } + val jar = tmpdir.resolve("jarWithoutModuleInfoClass.jar") + AbstractCliTest.executeCompilerGrabOutput( + K2JVMCompiler(), + listOf(fooKt.path, "-d", jar.path, "-include-runtime") + ) + + assertNoModuleInfoClass(jar) + } + private fun assertAllTimestampsAreReset(jar: File) { - val zis = JarInputStream(FileInputStream(jar)) - var entry: ZipEntry? = zis.nextEntry - while (entry != null) { + for (entry in JarFile(jar).entries()) { assertEquals(entry.time, DOS_EPOCH, "$entry timestamp should be reset") - entry = zis.nextEntry } } private fun assertNoTimestampsAreReset(jar: File) { - val zis = JarInputStream(FileInputStream(jar)) - var entry: ZipEntry? = zis.nextEntry - while (entry != null) { + for (entry in JarFile(jar).entries()) { assertNotEquals(entry.time, DOS_EPOCH, "$entry timestamp should not be reset") - entry = zis.nextEntry + } + } + + private fun assertNoModuleInfoClass(jar: File) { + for (entry in JarFile(jar).entries()) { + assertNotEquals( + "module-info.class", entry.name.substringAfterLast("/"), + "$entry is expected to be excluded from the resulting jar" + ) } } }