diff --git a/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/internal/RelocatorRemapper.kt b/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/internal/RelocatorRemapper.kt index bc3c1e688..dbb743c41 100644 --- a/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/internal/RelocatorRemapper.kt +++ b/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/internal/RelocatorRemapper.kt @@ -1,9 +1,6 @@ package com.github.jengelman.gradle.plugins.shadow.internal import com.github.jengelman.gradle.plugins.shadow.relocation.Relocator -import com.github.jengelman.gradle.plugins.shadow.relocation.relocatePath -import org.apache.tools.zip.UnixStat -import org.apache.tools.zip.ZipOutputStream import org.gradle.api.GradleException import org.gradle.api.file.FileCopyDetails import org.vafer.jdeb.shaded.objectweb.asm.ClassReader @@ -13,15 +10,10 @@ import org.vafer.jdeb.shaded.objectweb.asm.commons.ClassRemapper import org.vafer.jdeb.shaded.objectweb.asm.commons.Remapper /** - * Applies remapping to the given class with the specified relocation path. The remapped class is - * then written to the zip file. + * Applies remapping to the given class file using the provided relocators and returns the + * (possibly) remapped class bytes. If no remapping is required, the original bytes are returned. */ -internal fun FileCopyDetails.remapClass( - relocators: Set, - zipOutStr: ZipOutputStream, - preserveFileTimestamps: Boolean, - lastModified: Long, -) = +internal fun FileCopyDetails.remapClass(relocators: Set): ByteArray = file.readBytes().let { bytes -> var modified = false val remapper = RelocatorRemapper(relocators) { modified = true } @@ -42,20 +34,7 @@ internal fun FileCopyDetails.remapClass( } // If we didn't need to change anything, keep the original bytes as-is. - val newBytes = if (modified) cw.toByteArray() else bytes - - // Temporarily remove the multi-release prefix. - val multiReleasePrefix = "^META-INF/versions/\\d+/".toRegex().find(path)?.value.orEmpty() - val newPath = path.replace(multiReleasePrefix, "") - val relocatedPath = multiReleasePrefix + relocators.relocatePath(newPath) - val entry = - zipEntry(relocatedPath, preserveFileTimestamps, lastModified) { - unixMode = UnixStat.FILE_FLAG or permissions.toUnixNumeric() - } - // Now we put it back on so the class file is written out with the right extension. - zipOutStr.putNextEntry(entry) - zipOutStr.write(newBytes) - zipOutStr.closeEntry() + if (modified) cw.toByteArray() else bytes } /** diff --git a/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/tasks/ShadowCopyAction.kt b/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/tasks/ShadowCopyAction.kt index 4e445d102..1cb0039c3 100644 --- a/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/tasks/ShadowCopyAction.kt +++ b/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/tasks/ShadowCopyAction.kt @@ -174,12 +174,13 @@ constructor( if (relocators.isEmpty()) { fileDetails.writeToZip(path) } else { - fileDetails.remapClass( - relocators = relocators, - zipOutStr = zipOutStr, - preserveFileTimestamps = preserveFileTimestamps, - lastModified = fileDetails.lastModified, - ) + with(fileDetails) { + // Temporarily remove the multi-release prefix. + val multiReleasePrefix = multiReleaseRegex.find(path)?.value.orEmpty() + val newPath = path.replace(multiReleasePrefix, "") + val relocatedPath = multiReleasePrefix + relocators.relocatePath(newPath) + writeToZip(entryName = relocatedPath, bytes = remapClass(relocators = relocators)) + } } } enableKotlinModuleRemapping && path.endsWith(".kotlin_module") -> { @@ -246,13 +247,7 @@ constructor( // matter to the compiler. else -> path.replace(".kotlin_module", ".shadow.kotlin_module") } - val entry = - zipEntry(entryName, preserveFileTimestamps, lastModified) { - unixMode = UnixStat.FILE_FLAG or permissions.toUnixNumeric() - } - zipOutStr.putNextEntry(entry) - zipOutStr.write(newBytes) - zipOutStr.closeEntry() + writeToZip(entryName = entryName, bytes = newBytes) } private fun transform(fileDetails: FileCopyDetails, path: String): Boolean { @@ -265,19 +260,24 @@ constructor( return true } - private fun FileCopyDetails.writeToZip(entryName: String) { + private fun FileCopyDetails.writeToZip(entryName: String, bytes: ByteArray? = null) { val entry = zipEntry(entryName, preserveFileTimestamps, lastModified) { unixMode = UnixStat.FILE_FLAG or permissions.toUnixNumeric() } zipOutStr.putNextEntry(entry) - copyTo(zipOutStr) + if (bytes == null) { + copyTo(zipOutStr) + } else { + zipOutStr.write(bytes) + } zipOutStr.closeEntry() } } public companion object { private val logger = Logging.getLogger(ShadowCopyAction::class.java) + private val multiReleaseRegex = "^META-INF/versions/\\d+/".toRegex() private val ZipOutputStream.entries: List get() =