Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ public String toString() {
}
}

public static void patchJar(File inputJar, File outputJar, Collection<PatcherInfo> patchers) {
patchJar(inputJar, outputJar, patchers, true);
}

/**
* Patches the classes in the input JAR file, using the collection of patchers. Each patcher specifies a target class (its jar entry
* name) and the SHA256 digest on the class bytes.
Expand All @@ -69,8 +73,10 @@ public String toString() {
* @param inputFile the JAR file to patch
* @param outputFile the output (patched) JAR file
* @param patchers list of patcher info (classes to patch (jar entry name + optional SHA256 digest) and ASM visitor to transform them)
* @param preserveManifest whether to include the manifest file from the input JAR; set this to false when patching a signed JAR,
* otherwise the patched classes will fail to load at runtime due to mismatched signatures
*/
public static void patchJar(File inputFile, File outputFile, Collection<PatcherInfo> patchers) {
public static void patchJar(File inputFile, File outputFile, Collection<PatcherInfo> patchers, boolean preserveManifest) {
var classPatchers = patchers.stream().collect(Collectors.toMap(PatcherInfo::jarEntryName, Function.identity()));
var mismatchedClasses = new ArrayList<MismatchInfo>();
try (JarFile jarFile = new JarFile(inputFile); JarOutputStream jos = new JarOutputStream(new FileOutputStream(outputFile))) {
Expand Down Expand Up @@ -101,9 +107,11 @@ public static void patchJar(File inputFile, File outputFile, Collection<PatcherI
);
}
} else {
// Read the entry's data and write it to the new JAR
try (InputStream is = jarFile.getInputStream(entry)) {
is.transferTo(jos);
if (preserveManifest || entryName.endsWith("MANIFEST.MF") == false) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why endsWith? We should know the complete path of the manifest right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no particular reason - I've changed it to use equals instead

// Read the entry's data and write it to the new JAR
try (InputStream is = jarFile.getInputStream(entry)) {
is.transferTo(jos);
}
}
}
jos.closeEntry();
Expand Down
5 changes: 5 additions & 0 deletions docs/changelog/128613.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
pr: 128613
summary: Improve support for bytecode patching signed jars
area: Infra/Core
type: enhancement
issues: []
Loading