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:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
* Copyright 2012-2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -47,6 +47,7 @@ import org.springframework.util.FileCopyUtils;
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
* @author Madhura Bhave
|
||||
* @author Scott Frederick
|
||||
*/
|
||||
public abstract class AbstractExecutableArchiveLauncherTests {
|
||||
|
||||
@@ -80,9 +81,9 @@ public abstract class AbstractExecutableArchiveLauncherTests {
|
||||
if (indexed) {
|
||||
jarOutputStream.putNextEntry(new JarEntry(entryPrefix + "/classpath.idx"));
|
||||
Writer writer = new OutputStreamWriter(jarOutputStream, StandardCharsets.UTF_8);
|
||||
writer.write("- \"BOOT-INF/lib/foo.jar\"\n");
|
||||
writer.write("- \"BOOT-INF/lib/bar.jar\"\n");
|
||||
writer.write("- \"BOOT-INF/lib/baz.jar\"\n");
|
||||
writer.write("- \"" + entryPrefix + "/lib/foo.jar\"\n");
|
||||
writer.write("- \"" + entryPrefix + "/lib/bar.jar\"\n");
|
||||
writer.write("- \"" + entryPrefix + "/lib/baz.jar\"\n");
|
||||
writer.flush();
|
||||
jarOutputStream.closeEntry();
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
* Copyright 2012-2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -18,7 +18,11 @@ package org.springframework.boot.loader;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
@@ -33,6 +37,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
* Tests for {@link WarLauncher}.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
* @author Scott Frederick
|
||||
*/
|
||||
class WarLauncherTests extends AbstractExecutableArchiveLauncherTests {
|
||||
|
||||
@@ -66,6 +71,29 @@ class WarLauncherTests extends AbstractExecutableArchiveLauncherTests {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void explodedWarShouldPreserveClasspathOrderWhenIndexPresent() throws Exception {
|
||||
File explodedRoot = explode(createJarArchive("archive.war", "WEB-INF", true, Collections.emptyList()));
|
||||
WarLauncher launcher = new WarLauncher(new ExplodedArchive(explodedRoot, true));
|
||||
Iterator<Archive> archives = launcher.getClassPathArchivesIterator();
|
||||
URLClassLoader classLoader = (URLClassLoader) launcher.createClassLoader(archives);
|
||||
URL[] urls = classLoader.getURLs();
|
||||
assertThat(urls).containsExactly(getExpectedFileUrls(explodedRoot));
|
||||
}
|
||||
|
||||
@Test
|
||||
void warFilesPresentInWebInfLibsAndNotInClasspathIndexShouldBeAddedAfterWebInfClasses() throws Exception {
|
||||
ArrayList<String> extraLibs = new ArrayList<>(Arrays.asList("extra-1.jar", "extra-2.jar"));
|
||||
File explodedRoot = explode(createJarArchive("archive.war", "WEB-INF", true, extraLibs));
|
||||
WarLauncher launcher = new WarLauncher(new ExplodedArchive(explodedRoot, true));
|
||||
Iterator<Archive> archives = launcher.getClassPathArchivesIterator();
|
||||
URLClassLoader classLoader = (URLClassLoader) launcher.createClassLoader(archives);
|
||||
URL[] urls = classLoader.getURLs();
|
||||
List<File> expectedFiles = getExpectedFilesWithExtraLibs(explodedRoot);
|
||||
URL[] expectedFileUrls = expectedFiles.stream().map(this::toUrl).toArray(URL[]::new);
|
||||
assertThat(urls).containsExactly(expectedFileUrls);
|
||||
}
|
||||
|
||||
protected final URL[] getExpectedFileUrls(File explodedRoot) {
|
||||
return getExpectedFiles(explodedRoot).stream().map(this::toUrl).toArray(URL[]::new);
|
||||
}
|
||||
@@ -79,4 +107,15 @@ class WarLauncherTests extends AbstractExecutableArchiveLauncherTests {
|
||||
return expected;
|
||||
}
|
||||
|
||||
protected final List<File> getExpectedFilesWithExtraLibs(File parent) {
|
||||
List<File> expected = new ArrayList<>();
|
||||
expected.add(new File(parent, "WEB-INF/classes"));
|
||||
expected.add(new File(parent, "WEB-INF/lib/extra-1.jar"));
|
||||
expected.add(new File(parent, "WEB-INF/lib/extra-2.jar"));
|
||||
expected.add(new File(parent, "WEB-INF/lib/foo.jar"));
|
||||
expected.add(new File(parent, "WEB-INF/lib/bar.jar"));
|
||||
expected.add(new File(parent, "WEB-INF/lib/baz.jar"));
|
||||
return expected;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user