Skip to content

Commit 5111a33

Browse files
CopilotGoooler
authored andcommitted
Apply suggestions
- Fix ConstantValueAttribute remapping and skipStringConstants short-circuit in RelocatorRemapper - Fix field access flags preservation and module exports/opens relocation in RelocatorRemapper - Fix class descriptor derivation and annotation string constant relocation Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
1 parent 7911a27 commit 5111a33

File tree

3 files changed

+89
-8
lines changed

3 files changed

+89
-8
lines changed

src/functionalTest/kotlin/com/github/jengelman/gradle/plugins/shadow/RelocationTest.kt

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -533,6 +533,45 @@ class RelocationTest : BasePluginTest() {
533533
}
534534
}
535535

536+
@Test
537+
fun relocateAnnotationStringConstants() {
538+
writeClass {
539+
"""
540+
package my;
541+
import java.lang.annotation.Retention;
542+
import java.lang.annotation.RetentionPolicy;
543+
@Retention(RetentionPolicy.RUNTIME)
544+
@interface MyAnnotation {
545+
String value();
546+
}
547+
@MyAnnotation("foo.Bar")
548+
public class Main {
549+
public static void main(String[] args) {
550+
MyAnnotation ann = Main.class.getAnnotation(MyAnnotation.class);
551+
System.out.println(ann.value());
552+
}
553+
}
554+
"""
555+
.trimIndent()
556+
}
557+
projectScript.appendText(
558+
"""
559+
$shadowJarTask {
560+
manifest {
561+
attributes '$mainClassAttributeKey': 'my.Main'
562+
}
563+
relocate('foo', 'shadow.foo')
564+
}
565+
"""
566+
.trimIndent()
567+
)
568+
569+
runWithSuccess(shadowJarPath)
570+
val result = runProcess("java", "-jar", outputShadowedJar.use { it.toString() })
571+
572+
assertThat(result).contains("shadow.foo.Bar")
573+
}
574+
536575
@Issue("https://github.com/GradleUp/shadow/issues/1403")
537576
@Test
538577
fun relocateMultiClassSignatureStringConstants() {

src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/internal/RelocatorRemapper.kt

Lines changed: 48 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,14 @@ import java.lang.classfile.Signature
1919
import java.lang.classfile.Superclass
2020
import java.lang.classfile.TypeAnnotation
2121
import java.lang.classfile.attribute.AnnotationDefaultAttribute
22+
import java.lang.classfile.attribute.ConstantValueAttribute
2223
import java.lang.classfile.attribute.EnclosingMethodAttribute
2324
import java.lang.classfile.attribute.ExceptionsAttribute
2425
import java.lang.classfile.attribute.InnerClassInfo
2526
import java.lang.classfile.attribute.InnerClassesAttribute
2627
import java.lang.classfile.attribute.ModuleAttribute
28+
import java.lang.classfile.attribute.ModuleExportInfo
29+
import java.lang.classfile.attribute.ModuleOpenInfo
2730
import java.lang.classfile.attribute.ModuleProvideInfo
2831
import java.lang.classfile.attribute.NestHostAttribute
2932
import java.lang.classfile.attribute.NestMembersAttribute
@@ -37,6 +40,7 @@ import java.lang.classfile.attribute.RuntimeVisibleAnnotationsAttribute
3740
import java.lang.classfile.attribute.RuntimeVisibleParameterAnnotationsAttribute
3841
import java.lang.classfile.attribute.RuntimeVisibleTypeAnnotationsAttribute
3942
import java.lang.classfile.attribute.SignatureAttribute
43+
import java.lang.classfile.constantpool.StringEntry
4044
import java.lang.classfile.instruction.ConstantInstruction
4145
import java.lang.classfile.instruction.ExceptionCatch
4246
import java.lang.classfile.instruction.FieldInstruction
@@ -55,6 +59,7 @@ import java.lang.constant.DynamicCallSiteDesc
5559
import java.lang.constant.DynamicConstantDesc
5660
import java.lang.constant.MethodHandleDesc
5761
import java.lang.constant.MethodTypeDesc
62+
import java.lang.constant.PackageDesc
5863
import java.util.regex.Pattern
5964

6065
/**
@@ -75,7 +80,7 @@ internal class RelocatorRemapper(
7580
cle.fieldName().stringValue(),
7681
mapClassDesc(ClassDesc.ofDescriptor(cle.fieldType().stringValue())),
7782
) { fb ->
78-
fb.transform(cle, asFieldTransform())
83+
fb.withFlags(cle.flags().flagsMask()).transform(cle, asFieldTransform())
7984
}
8085
is MethodModel ->
8186
clb.withMethod(
@@ -123,8 +128,28 @@ internal class RelocatorRemapper(
123128
cle.moduleFlagsMask(),
124129
cle.moduleVersion().orElse(null),
125130
cle.requires(),
126-
cle.exports(),
127-
cle.opens(),
131+
cle.exports().map { mei ->
132+
ModuleExportInfo.of(
133+
clb
134+
.constantPool()
135+
.packageEntry(
136+
PackageDesc.ofInternalName(map(mei.exportedPackage().asSymbol().internalName()))
137+
),
138+
mei.exportsFlagsMask(),
139+
mei.exportsTo(),
140+
)
141+
},
142+
cle.opens().map { moi ->
143+
ModuleOpenInfo.of(
144+
clb
145+
.constantPool()
146+
.packageEntry(
147+
PackageDesc.ofInternalName(map(moi.openedPackage().asSymbol().internalName()))
148+
),
149+
moi.opensFlagsMask(),
150+
moi.opensTo(),
151+
)
152+
},
128153
cle.uses().map { clb.constantPool().classEntry(mapClassDesc(it.asSymbol())!!) },
129154
cle.provides().map { mp ->
130155
ModuleProvideInfo.of(
@@ -160,6 +185,15 @@ internal class RelocatorRemapper(
160185

161186
private fun asFieldTransform(): FieldTransform = FieldTransform { fb, fe ->
162187
when (fe) {
188+
is ConstantValueAttribute -> {
189+
val constant = fe.constant()
190+
if (constant is StringEntry) {
191+
val remapped = map(constant.stringValue(), true)
192+
fb.with(ConstantValueAttribute.of(fb.constantPool().stringEntry(remapped)))
193+
} else {
194+
fb.with(fe)
195+
}
196+
}
163197
is SignatureAttribute -> fb.with(SignatureAttribute.of(mapSignature(fe.asTypeSignature())))
164198
is RuntimeVisibleAnnotationsAttribute ->
165199
fb.with(RuntimeVisibleAnnotationsAttribute.of(mapAnnotations(fe.annotations())))
@@ -436,7 +470,16 @@ internal class RelocatorRemapper(
436470
AnnotationValue.ofAnnotation(mapAnnotation(valObj.annotation()))
437471
is AnnotationValue.OfArray ->
438472
AnnotationValue.ofArray(valObj.values().map(this::mapAnnotationValue))
439-
is AnnotationValue.OfConstant -> valObj
473+
is AnnotationValue.OfConstant -> {
474+
if (valObj is AnnotationValue.OfString) {
475+
val str = valObj.stringValue()
476+
// mapLiterals=true enables the skipStringConstants check in each relocator.
477+
val mapped = map(str, mapLiterals = true)
478+
if (mapped != str) AnnotationValue.ofString(mapped) else valObj
479+
} else {
480+
valObj
481+
}
482+
}
440483
is AnnotationValue.OfClass -> AnnotationValue.ofClass(mapClassDesc(valObj.classSymbol())!!)
441484
is AnnotationValue.OfEnum ->
442485
AnnotationValue.ofEnum(
@@ -486,7 +529,7 @@ internal class RelocatorRemapper(
486529

487530
for (relocator in relocators) {
488531
if (mapLiterals && relocator.skipStringConstants) {
489-
return name
532+
continue
490533
} else if (relocator.canRelocateClass(newName)) {
491534
return prefix + relocator.relocateClass(newName) + suffix
492535
} else if (relocator.canRelocatePath(newName)) {

src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/tasks/ShadowCopyAction.kt

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ import com.github.jengelman.gradle.plugins.shadow.transformers.ResourceTransform
1414
import com.github.jengelman.gradle.plugins.shadow.transformers.TransformerContext
1515
import java.io.File
1616
import java.lang.classfile.ClassFile
17-
import java.lang.constant.ClassDesc
1817
import java.util.GregorianCalendar
1918
import java.util.zip.ZipException
2019
import kotlin.metadata.jvm.KmModule
@@ -212,14 +211,14 @@ constructor(
212211
file.readBytes().let { bytes ->
213212
var modified = false
214213
val multiReleasePrefix = "^META-INF/versions/\\d+/".toRegex().find(path)?.value.orEmpty()
215-
val internalClassName = path.replace(multiReleasePrefix, "").removeSuffix(".class")
216214
val remapper = RelocatorRemapper(relocators) { modified = true }
217215

218216
val newBytes =
219217
try {
220218
val classFile = ClassFile.of()
221219
val classModel = classFile.parse(bytes)
222-
val newClassDesc = remapper.mapClassDesc(ClassDesc.ofInternalName(internalClassName))!!
220+
val originalClassDesc = classModel.thisClass().asSymbol()
221+
val newClassDesc = remapper.mapClassDesc(originalClassDesc)!!
223222
classFile.transformClass(classModel, newClassDesc, remapper.asClassTransform())
224223
} catch (t: Throwable) {
225224
throw GradleException("Error in Class-File API processing class $path", t)

0 commit comments

Comments
 (0)