Add classpath index support for exploded war archives
Update the Maven and Gradle packaging for war files so that a `classpath.idx` file is written into the archive that provides the original order of the classpath, as was previously done for jar files. The `WarLauncher` class will use this file when running as an exploded archive to ensure that the classpath order is the same as when running from the far war. Fixes gh-19875
This commit is contained in:
@@ -75,17 +75,20 @@ abstract class AbstractArchiveIntegrationTests {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
Map<String, List<String>> index = new LinkedHashMap<>();
|
||||
String layerPrefix = "- ";
|
||||
String entryPrefix = " - ";
|
||||
ZipEntry indexEntry = jarFile.getEntry(getLayersIndexLocation());
|
||||
try (BufferedReader reader = new BufferedReader(new InputStreamReader(jarFile.getInputStream(indexEntry)))) {
|
||||
String line = reader.readLine();
|
||||
String layer = null;
|
||||
while (line != null) {
|
||||
if (line.startsWith("- ")) {
|
||||
layer = line.substring(3, line.length() - 2);
|
||||
if (line.startsWith(layerPrefix)) {
|
||||
layer = line.substring(layerPrefix.length() + 1, line.length() - 2);
|
||||
index.put(layer, new ArrayList<>());
|
||||
}
|
||||
else if (line.startsWith(" - ")) {
|
||||
index.computeIfAbsent(layer, (key) -> new ArrayList<>()).add(line.substring(5, line.length() - 1));
|
||||
else if (line.startsWith(entryPrefix)) {
|
||||
index.computeIfAbsent(layer, (key) -> new ArrayList<>())
|
||||
.add(line.substring(entryPrefix.length() + 1, line.length() - 1));
|
||||
}
|
||||
line = reader.readLine();
|
||||
}
|
||||
@@ -97,6 +100,22 @@ abstract class AbstractArchiveIntegrationTests {
|
||||
return null;
|
||||
}
|
||||
|
||||
protected List<String> readClasspathIndex(JarFile jarFile, String location) throws IOException {
|
||||
List<String> index = new ArrayList<>();
|
||||
String entryPrefix = "- ";
|
||||
ZipEntry indexEntry = jarFile.getEntry(location);
|
||||
try (BufferedReader reader = new BufferedReader(new InputStreamReader(jarFile.getInputStream(indexEntry)))) {
|
||||
String line = reader.readLine();
|
||||
while (line != null) {
|
||||
if (line.startsWith(entryPrefix)) {
|
||||
index.add(line.substring(entryPrefix.length() + 1, line.length() - 1));
|
||||
}
|
||||
line = reader.readLine();
|
||||
}
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
static final class JarAssert extends AbstractAssert<JarAssert, File> {
|
||||
|
||||
private JarAssert(File actual) {
|
||||
|
||||
@@ -372,6 +372,10 @@ class JarIntegrationTests extends AbstractArchiveIntegrationTests {
|
||||
assertThat(jar(repackaged)).manifest(
|
||||
(manifest) -> manifest.hasAttribute("Spring-Boot-Classpath-Index", "BOOT-INF/classpath.idx"));
|
||||
assertThat(jar(repackaged)).hasEntryWithName("BOOT-INF/classpath.idx");
|
||||
try (JarFile jarFile = new JarFile(repackaged)) {
|
||||
List<String> index = readClasspathIndex(jarFile, "BOOT-INF/classpath.idx");
|
||||
assertThat(index).allMatch((entry) -> entry.startsWith("BOOT-INF/lib/"));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -211,12 +211,17 @@ class WarIntegrationTests extends AbstractArchiveIntegrationTests {
|
||||
}
|
||||
|
||||
@TestTemplate
|
||||
void repackagedWarDoesNotContainClasspathIndex(MavenBuild mavenBuild) {
|
||||
void repackagedWarContainsClasspathIndex(MavenBuild mavenBuild) {
|
||||
mavenBuild.project("war").execute((project) -> {
|
||||
File repackaged = new File(project, "target/war-0.0.1.BUILD-SNAPSHOT.war");
|
||||
assertThat(jar(repackaged))
|
||||
.manifest((manifest) -> manifest.doesNotHaveAttribute("Spring-Boot-Classpath-Index"));
|
||||
assertThat(jar(repackaged)).doesNotHaveEntryWithName("BOOT-INF/classpath.idx");
|
||||
assertThat(jar(repackaged)).manifest(
|
||||
(manifest) -> manifest.hasAttribute("Spring-Boot-Classpath-Index", "WEB-INF/classpath.idx"));
|
||||
assertThat(jar(repackaged)).hasEntryWithName("WEB-INF/classpath.idx");
|
||||
try (JarFile jarFile = new JarFile(repackaged)) {
|
||||
List<String> index = readClasspathIndex(jarFile, "WEB-INF/classpath.idx");
|
||||
assertThat(index).allMatch(
|
||||
(entry) -> entry.startsWith("WEB-INF/lib/") || entry.startsWith("WEB-INF/lib-provided/"));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user