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:
@@ -500,9 +500,7 @@ abstract class AbstractBootArchiveTests<T extends Jar & BootArchive> {
|
||||
expected.add("- \"application\":");
|
||||
Set<String> applicationContents = new TreeSet<>();
|
||||
applicationContents.add(" - \"" + this.classesPath + "\"");
|
||||
if (archiveHasClasspathIndex()) {
|
||||
applicationContents.add(" - \"" + this.indexPath + "classpath.idx\"");
|
||||
}
|
||||
applicationContents.add(" - \"" + this.indexPath + "classpath.idx\"");
|
||||
applicationContents.add(" - \"" + this.indexPath + "layers.idx\"");
|
||||
applicationContents.add(" - \"META-INF/\"");
|
||||
expected.addAll(applicationContents);
|
||||
@@ -551,9 +549,7 @@ abstract class AbstractBootArchiveTests<T extends Jar & BootArchive> {
|
||||
Set<String> applicationContents = new TreeSet<>();
|
||||
applicationContents.add(" - \"" + this.classesPath + "application.properties\"");
|
||||
applicationContents.add(" - \"" + this.classesPath + "com/\"");
|
||||
if (archiveHasClasspathIndex()) {
|
||||
applicationContents.add(" - \"" + this.indexPath + "classpath.idx\"");
|
||||
}
|
||||
applicationContents.add(" - \"" + this.indexPath + "classpath.idx\"");
|
||||
applicationContents.add(" - \"" + this.indexPath + "layers.idx\"");
|
||||
applicationContents.add(" - \"META-INF/\"");
|
||||
applicationContents.add(" - \"org/\"");
|
||||
@@ -634,12 +630,14 @@ abstract class AbstractBootArchiveTests<T extends Jar & BootArchive> {
|
||||
return getTask().getArchiveFile().get().getAsFile();
|
||||
}
|
||||
|
||||
abstract void applyLayered(Action<LayeredSpec> action);
|
||||
|
||||
boolean archiveHasClasspathIndex() {
|
||||
return true;
|
||||
File createPopulatedJar() throws IOException {
|
||||
addContent();
|
||||
executeTask();
|
||||
return getTask().getArchiveFile().get().getAsFile();
|
||||
}
|
||||
|
||||
abstract void applyLayered(Action<LayeredSpec> action);
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
void addContent() throws IOException {
|
||||
this.task.getMainClass().set("com.example.Main");
|
||||
|
||||
@@ -103,12 +103,6 @@ class BootJarTests extends AbstractBootArchiveTests<BootJar> {
|
||||
}
|
||||
}
|
||||
|
||||
private File createPopulatedJar() throws IOException {
|
||||
addContent();
|
||||
executeTask();
|
||||
return getTask().getArchiveFile().get().getAsFile();
|
||||
}
|
||||
|
||||
@Override
|
||||
void applyLayered(Action<LayeredSpec> action) {
|
||||
getTask().layered(action);
|
||||
|
||||
@@ -26,6 +26,7 @@ import org.springframework.boot.gradle.junit.GradleCompatibility;
|
||||
* Integration tests for {@link BootWar}.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
* @author Scott Frederick
|
||||
*/
|
||||
@GradleCompatibility(configurationCache = true)
|
||||
class BootWarIntegrationTests extends AbstractBootArchiveIntegrationTests {
|
||||
@@ -37,7 +38,7 @@ class BootWarIntegrationTests extends AbstractBootArchiveIntegrationTests {
|
||||
@Override
|
||||
String[] getExpectedApplicationLayerContents(String... additionalFiles) {
|
||||
Set<String> contents = new TreeSet<>(Arrays.asList(additionalFiles));
|
||||
contents.addAll(Arrays.asList("WEB-INF/layers.idx", "META-INF/"));
|
||||
contents.addAll(Arrays.asList("WEB-INF/classpath.idx", "WEB-INF/layers.idx", "META-INF/"));
|
||||
return contents.toArray(new String[0]);
|
||||
}
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
* Tests for {@link BootWar}.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
* @author Scott Frederick
|
||||
*/
|
||||
class BootWarTests extends AbstractBootArchiveTests<BootWar> {
|
||||
|
||||
@@ -109,6 +110,28 @@ class BootWarTests extends AbstractBootArchiveTests<BootWar> {
|
||||
.containsSubsequence("WEB-INF/lib/library.jar", "WEB-INF/lib-provided/provided-library.jar");
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenWarIsLayeredClasspathIndexPointsToLayeredLibs() throws IOException {
|
||||
try (JarFile jarFile = new JarFile(createLayeredJar())) {
|
||||
assertThat(entryLines(jarFile, "WEB-INF/classpath.idx")).containsExactly(
|
||||
"- \"WEB-INF/lib/first-library.jar\"", "- \"WEB-INF/lib/second-library.jar\"",
|
||||
"- \"WEB-INF/lib/third-library-SNAPSHOT.jar\"", "- \"WEB-INF/lib/first-project-library.jar\"",
|
||||
"- \"WEB-INF/lib/second-project-library-SNAPSHOT.jar\"");
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void classpathIndexPointsToWebInfLibs() throws IOException {
|
||||
try (JarFile jarFile = new JarFile(createPopulatedJar())) {
|
||||
assertThat(jarFile.getManifest().getMainAttributes().getValue("Spring-Boot-Classpath-Index"))
|
||||
.isEqualTo("WEB-INF/classpath.idx");
|
||||
assertThat(entryLines(jarFile, "WEB-INF/classpath.idx")).containsExactly(
|
||||
"- \"WEB-INF/lib/first-library.jar\"", "- \"WEB-INF/lib/second-library.jar\"",
|
||||
"- \"WEB-INF/lib/third-library-SNAPSHOT.jar\"", "- \"WEB-INF/lib/first-project-library.jar\"",
|
||||
"- \"WEB-INF/lib/second-project-library-SNAPSHOT.jar\"");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void executeTask() {
|
||||
getTask().copy();
|
||||
@@ -124,9 +147,4 @@ class BootWarTests extends AbstractBootArchiveTests<BootWar> {
|
||||
getTask().layered(action);
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean archiveHasClasspathIndex() {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user