Skip to content

Commit bceed13

Browse files
committed
Jar files added after build time should be added to classpath
Fixes gh-19973
1 parent b281af0 commit bceed13

File tree

4 files changed

+46
-7
lines changed

4 files changed

+46
-7
lines changed

spring-boot-project/spring-boot-tools/spring-boot-loader/src/main/java/org/springframework/boot/loader/ClassPathIndexFile.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,13 @@ boolean containsFolder(String name) {
7272
return this.folders.contains(name);
7373
}
7474

75+
boolean containsEntry(String name) {
76+
if (name == null || name.isEmpty()) {
77+
return false;
78+
}
79+
return this.lines.contains(name);
80+
}
81+
7582
List<URL> getUrls() {
7683
return Collections.unmodifiableList(this.lines.stream().map(this::asUrl).collect(Collectors.toList()));
7784
}

spring-boot-project/spring-boot-tools/spring-boot-loader/src/main/java/org/springframework/boot/loader/ExecutableArchiveLauncher.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -101,17 +101,18 @@ private int guessClassPathSize() {
101101

102102
@Override
103103
protected Iterator<Archive> getClassPathArchivesIterator() throws Exception {
104-
Archive.EntryFilter searchFilter = (entry) -> isSearchCandidate(entry) && !isFolderIndexed(entry);
105-
Iterator<Archive> archives = this.archive.getNestedArchives(searchFilter, this::isNestedArchive);
104+
Archive.EntryFilter searchFilter = this::isSearchCandidate;
105+
Iterator<Archive> archives = this.archive.getNestedArchives(searchFilter,
106+
(entry) -> isNestedArchive(entry) && !isEntryIndexed(entry));
106107
if (isPostProcessingClassPathArchives()) {
107108
archives = applyClassPathArchivePostProcessing(archives);
108109
}
109110
return archives;
110111
}
111112

112-
private boolean isFolderIndexed(Archive.Entry entry) {
113+
private boolean isEntryIndexed(Archive.Entry entry) {
113114
if (this.classPathIndex != null) {
114-
return this.classPathIndex.containsFolder(entry.getName());
115+
return this.classPathIndex.containsEntry(entry.getName());
115116
}
116117
return false;
117118
}

spring-boot-project/spring-boot-tools/spring-boot-loader/src/test/java/org/springframework/boot/loader/AbstractExecutableArchiveLauncherTests.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import java.net.MalformedURLException;
2626
import java.net.URL;
2727
import java.nio.charset.StandardCharsets;
28+
import java.util.Collections;
2829
import java.util.Enumeration;
2930
import java.util.LinkedHashSet;
3031
import java.util.List;
@@ -52,11 +53,12 @@ public abstract class AbstractExecutableArchiveLauncherTests {
5253
File tempDir;
5354

5455
protected File createJarArchive(String name, String entryPrefix) throws IOException {
55-
return createJarArchive(name, entryPrefix, false);
56+
return createJarArchive(name, entryPrefix, false, Collections.emptyList());
5657
}
5758

5859
@SuppressWarnings("resource")
59-
protected File createJarArchive(String name, String entryPrefix, boolean indexed) throws IOException {
60+
protected File createJarArchive(String name, String entryPrefix, boolean indexed, List<String> extraLibs)
61+
throws IOException {
6062
File archive = new File(this.tempDir, name);
6163
JarOutputStream jarOutputStream = new JarOutputStream(new FileOutputStream(archive));
6264
jarOutputStream.putNextEntry(new JarEntry(entryPrefix + "/"));
@@ -74,6 +76,9 @@ protected File createJarArchive(String name, String entryPrefix, boolean indexed
7476
addNestedJars(entryPrefix, "/lib/foo.jar", jarOutputStream);
7577
addNestedJars(entryPrefix, "/lib/bar.jar", jarOutputStream);
7678
addNestedJars(entryPrefix, "/lib/baz.jar", jarOutputStream);
79+
for (String lib : extraLibs) {
80+
addNestedJars(entryPrefix, "/lib/" + lib, jarOutputStream);
81+
}
7782
jarOutputStream.close();
7883
return archive;
7984
}

spring-boot-project/spring-boot-tools/spring-boot-loader/src/test/java/org/springframework/boot/loader/JarLauncherTests.java

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
import java.net.URL;
2121
import java.net.URLClassLoader;
2222
import java.util.ArrayList;
23+
import java.util.Arrays;
24+
import java.util.Collections;
2325
import java.util.Iterator;
2426
import java.util.List;
2527

@@ -72,14 +74,27 @@ void archivedJarHasOnlyBootInfClassesAndContentsOfBootInfLibOnClasspath() throws
7274

7375
@Test
7476
void explodedJarShouldPreserveClasspathOrderWhenIndexPresent() throws Exception {
75-
File explodedRoot = explode(createJarArchive("archive.jar", "BOOT-INF", true));
77+
File explodedRoot = explode(createJarArchive("archive.jar", "BOOT-INF", true, Collections.emptyList()));
7678
JarLauncher launcher = new JarLauncher(new ExplodedArchive(explodedRoot, true));
7779
Iterator<Archive> archives = launcher.getClassPathArchivesIterator();
7880
URLClassLoader classLoader = (URLClassLoader) launcher.createClassLoader(archives);
7981
URL[] urls = classLoader.getURLs();
8082
assertThat(urls).containsExactly(getExpectedFileUrls(explodedRoot));
8183
}
8284

85+
@Test
86+
void jarFilesPresentInBootInfLibsAndNotInClasspathIndexShouldBeAddedAfterBootInfClasses() throws Exception {
87+
ArrayList<String> extraLibs = new ArrayList<>(Arrays.asList("extra-1.jar", "extra-2.jar"));
88+
File explodedRoot = explode(createJarArchive("archive.jar", "BOOT-INF", true, extraLibs));
89+
JarLauncher launcher = new JarLauncher(new ExplodedArchive(explodedRoot, true));
90+
Iterator<Archive> archives = launcher.getClassPathArchivesIterator();
91+
URLClassLoader classLoader = (URLClassLoader) launcher.createClassLoader(archives);
92+
URL[] urls = classLoader.getURLs();
93+
List<File> expectedFiles = getExpectedFilesWithExtraLibs(explodedRoot);
94+
URL[] expectedFileUrls = expectedFiles.stream().map(this::toUrl).toArray(URL[]::new);
95+
assertThat(urls).containsExactly(expectedFileUrls);
96+
}
97+
8398
protected final URL[] getExpectedFileUrls(File explodedRoot) {
8499
return getExpectedFiles(explodedRoot).stream().map(this::toUrl).toArray(URL[]::new);
85100
}
@@ -93,4 +108,15 @@ protected final List<File> getExpectedFiles(File parent) {
93108
return expected;
94109
}
95110

111+
protected final List<File> getExpectedFilesWithExtraLibs(File parent) {
112+
List<File> expected = new ArrayList<>();
113+
expected.add(new File(parent, "BOOT-INF/classes"));
114+
expected.add(new File(parent, "BOOT-INF/lib/extra-1.jar"));
115+
expected.add(new File(parent, "BOOT-INF/lib/extra-2.jar"));
116+
expected.add(new File(parent, "BOOT-INF/lib/foo.jar"));
117+
expected.add(new File(parent, "BOOT-INF/lib/bar.jar"));
118+
expected.add(new File(parent, "BOOT-INF/lib/baz.jar"));
119+
return expected;
120+
}
121+
96122
}

0 commit comments

Comments
 (0)