It is possible that Repackager
can run on an already repackaged archive. We have a check in place that skips repackaging if the source and the target File is identical and the source is a repackaged archive.
If the source does not match the target, repackaging will occur, reading the main class from the manifest of the source. Doing so means the target repackaged archive uses JarLauncher
as "main app" which will create a StackOverflow.
This is basically #16202 and what happens when you run repackaging twice with and without a finalName
.
Comment From: ielatif
@snicoll I am interested to work on it.
We have a check in place that skips repackaging if the source and the target File is identical and the source is a repackaged archive.
here is the check you mentioned : https://github.com/spring-projects/spring-boot/blob/36c1c051b8106371d37f8a747cea0e369a8e5c84/spring-boot-project/spring-boot-tools/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/Repackager.java#L184-L186
I think keeping the check that source is already repackaged and removing the check for source and destination are identical will solve it.
The check for source and destination are identical will be still handled here : https://github.com/spring-projects/spring-boot/blob/36c1c051b8106371d37f8a747cea0e369a8e5c84/spring-boot-project/spring-boot-tools/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/Repackager.java#L187-L191
Comment From: snicoll
@snicoll I am interested to work on it.
Thank you for offering to help. I am not sure yet how to proceed with this one but if you want to give it a try, feel free to do do so.
Comment From: ielatif
@snicoll I approached this issue with different ways and found that repackage detection works just fine. The issue here is to allow multiple executions even those that runs multiple times.
I ended up with this solution :
if is already repackaged :
if backup file exists then repackage from backup file
otherwise repackage from original jar
File backupFile = getBackupFile();
if (alreadyRepackaged()) {
if (backupFile.exists()) {
try (JarFile jarFileSource = new JarFile(backupFile)) {
repackage(jarFileSource, destination, libraries, launchScript);
}
}
else {
repackage(destination, libraries, launchScript);
}
return;
}
Comment From: snicoll
We've been looking at this one and were unable to reproduce it. A double execution plus exploiting a bug in Maven makes it quite unlikely to happen in practice but we can reopen if we manage to reproduce it with a recent version.