11package com.github.jengelman.gradle.plugins.shadow.internal
22
33import com.github.jengelman.gradle.plugins.shadow.relocation.Relocator
4- import com.github.jengelman.gradle.plugins.shadow.relocation.relocateClass
5- import com.github.jengelman.gradle.plugins.shadow.relocation.relocatePath
6- import java.util.regex.Pattern
7- import java.util.zip.ZipException
8- import org.apache.tools.zip.UnixStat
9- import org.apache.tools.zip.ZipOutputStream
104import org.gradle.api.GradleException
115import org.gradle.api.file.FileCopyDetails
12- import org.gradle.api.logging.Logger
136import org.vafer.jdeb.shaded.objectweb.asm.ClassReader
147import org.vafer.jdeb.shaded.objectweb.asm.ClassWriter
158import org.vafer.jdeb.shaded.objectweb.asm.Opcodes
169import org.vafer.jdeb.shaded.objectweb.asm.commons.ClassRemapper
1710import org.vafer.jdeb.shaded.objectweb.asm.commons.Remapper
1811
1912/* *
20- * Modified from
21- * [org.apache.maven.plugins.shade.DefaultShader.RelocatorRemapper](https://github.com/apache/maven-shade-plugin/blob/83c123d1f9c5f6927af2aca12ee322b5168a7c63/src/main/java/org/apache/maven/plugins/shade/DefaultShader.java#L689-L772).
22- * Modified from
23- * [org.apache.maven.plugins.shade.DefaultShader.DefaultPackageMapper](https://github.com/apache/maven-shade-plugin/blob/199ffaecd26a912527173ed4edae366e48a00998/src/main/java/org/apache/maven/plugins/shade/DefaultShader.java#L737-L774).
24- *
25- * @author John Engelman
26- */
27- internal class RelocatorRemapper (
28- private val relocators : Set <Relocator >,
29- private val onModified : () -> Unit = {},
30- ) : Remapper(Opcodes .ASM9 ) {
31-
32- override fun mapValue (value : Any ): Any {
33- return if (value is String ) {
34- mapName(value, mapLiterals = true )
35- } else {
36- super .mapValue(value)
37- }
38- }
39-
40- override fun map (internalName : String ): String = mapName(internalName)
41-
42- private fun mapName (name : String , mapLiterals : Boolean = false): String {
43- // Maybe a list of types.
44- val newName = name.split(' ;' ).joinToString(" ;" ) { mapNameImpl(it, mapLiterals) }
45-
46- if (newName != name) {
47- onModified()
48- }
49- return newName
50- }
51-
52- private fun mapNameImpl (name : String , mapLiterals : Boolean ): String {
53- var newName = name
54- var prefix = " "
55- var suffix = " "
56-
57- val matcher = classPattern.matcher(newName)
58- if (matcher.matches()) {
59- prefix = matcher.group(1 ) + " L"
60- suffix = " "
61- newName = matcher.group(2 )
62- }
63-
64- for (relocator in relocators) {
65- if (mapLiterals && relocator.skipStringConstants) {
66- return name
67- } else if (relocator.canRelocateClass(newName)) {
68- return prefix + relocator.relocateClass(newName) + suffix
69- } else if (relocator.canRelocatePath(newName)) {
70- return prefix + relocator.relocatePath(newName) + suffix
71- }
72- }
73-
74- return name
75- }
76-
77- private companion object {
78- /* * https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html */
79- val classPattern: Pattern = Pattern .compile(" ([\\ [()BCDFIJSZ]*)?L([^;]+);?" )
80- }
81- }
82-
83- /* *
84- * Applies remapping to the given class with the specified relocation path. The remapped class is
85- * then written to the zip file.
13+ * Applies remapping to the given class file using the provided relocators and returns the
14+ * (possibly) remapped class bytes. If no remapping is required, the original bytes are returned.
8615 */
87- internal fun FileCopyDetails.remapClass (
88- relocators : Set <Relocator >,
89- zipOutStr : ZipOutputStream ,
90- preserveFileTimestamps : Boolean ,
91- lastModified : Long ,
92- logger : Logger ,
93- ) =
16+ internal fun FileCopyDetails.remapClass (relocators : Set <Relocator >): ByteArray =
9417 file.readBytes().let { bytes ->
9518 var modified = false
9619 val remapper = RelocatorRemapper (relocators) { modified = true }
9720
98- // We don't pass the ClassReader here. This forces the ClassWriter to rebuild the constant
99- // pool.
100- // Copying the original constant pool should be avoided because it would keep references
101- // to the original class names. This is not a problem at runtime (because these entries in
102- // the
103- // constant pool are never used), but confuses some tools such as Felix's
104- // maven-bundle-plugin
105- // that use the constant pool to determine the dependencies of a class.
21+ // We don't pass the ClassReader here. This forces the ClassWriter to rebuild the constant pool.
22+ // Copying the original constant pool should be avoided because it would keep references to the
23+ // original class names. This is not a problem at runtime (because these entries in the constant
24+ // pool are never used), but confuses some tools such as Felix's maven-bundle-plugin that use
25+ // the constant pool to determine the dependencies of a class.
10626 val cw = ClassWriter (0 )
10727 val cr = ClassReader (bytes)
10828 val cv = ClassRemapper (cw, remapper)
@@ -113,28 +33,31 @@ internal fun FileCopyDetails.remapClass(
11333 throw GradleException (" Error in ASM processing class $path " , t)
11434 }
11535
116- val newBytes =
117- if (modified) {
118- cw.toByteArray()
119- } else {
120- // If we didn't need to change anything, keep the original bytes as-is
121- bytes
122- }
36+ // If we didn't need to change anything, keep the original bytes as-is.
37+ if (modified) cw.toByteArray() else bytes
38+ }
12339
124- // Temporarily remove the multi-release prefix.
125- val multiReleasePrefix = " ^META-INF/versions/\\ d+/" .toRegex().find(path)?.value.orEmpty()
126- val newPath = path.replace(multiReleasePrefix, " " )
127- val relocatedPath = multiReleasePrefix + relocators.relocatePath(newPath)
128- try {
129- val entry =
130- zipEntry(relocatedPath, preserveFileTimestamps, lastModified) {
131- unixMode = UnixStat .FILE_FLAG or permissions.toUnixNumeric()
132- }
133- // Now we put it back on so the class file is written out with the right extension.
134- zipOutStr.putNextEntry(entry)
135- zipOutStr.write(newBytes)
136- zipOutStr.closeEntry()
137- } catch (_: ZipException ) {
138- logger.warn(" We have a duplicate $relocatedPath in source project" )
40+ /* *
41+ * Modified from
42+ * [org.apache.maven.plugins.shade.DefaultShader.RelocatorRemapper](https://github.com/apache/maven-shade-plugin/blob/83c123d1f9c5f6927af2aca12ee322b5168a7c63/src/main/java/org/apache/maven/plugins/shade/DefaultShader.java#L689-L772).
43+ * Modified from
44+ * [org.apache.maven.plugins.shade.DefaultShader.DefaultPackageMapper](https://github.com/apache/maven-shade-plugin/blob/199ffaecd26a912527173ed4edae366e48a00998/src/main/java/org/apache/maven/plugins/shade/DefaultShader.java#L737-L774).
45+ *
46+ * @author John Engelman
47+ */
48+ private class RelocatorRemapper (
49+ private val relocators : Set <Relocator >,
50+ private val onModified : () -> Unit ,
51+ ) : Remapper(Opcodes .ASM9 ) {
52+
53+ override fun mapValue (value : Any ): Any {
54+ return if (value is String ) {
55+ relocators.mapName(name = value, mapLiterals = true , onModified = onModified)
56+ } else {
57+ super .mapValue(value)
13958 }
14059 }
60+
61+ override fun map (internalName : String ): String =
62+ relocators.mapName(name = internalName, onModified = onModified)
63+ }
0 commit comments