Jar files added after build time should be added to classpath
Fixes gh-19973
This commit is contained in:
parent
b281af0b9b
commit
bceed1305f
|
@ -72,6 +72,13 @@ final class ClassPathIndexFile {
|
||||||
return this.folders.contains(name);
|
return this.folders.contains(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean containsEntry(String name) {
|
||||||
|
if (name == null || name.isEmpty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return this.lines.contains(name);
|
||||||
|
}
|
||||||
|
|
||||||
List<URL> getUrls() {
|
List<URL> getUrls() {
|
||||||
return Collections.unmodifiableList(this.lines.stream().map(this::asUrl).collect(Collectors.toList()));
|
return Collections.unmodifiableList(this.lines.stream().map(this::asUrl).collect(Collectors.toList()));
|
||||||
}
|
}
|
||||||
|
|
|
@ -101,17 +101,18 @@ public abstract class ExecutableArchiveLauncher extends Launcher {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Iterator<Archive> getClassPathArchivesIterator() throws Exception {
|
protected Iterator<Archive> getClassPathArchivesIterator() throws Exception {
|
||||||
Archive.EntryFilter searchFilter = (entry) -> isSearchCandidate(entry) && !isFolderIndexed(entry);
|
Archive.EntryFilter searchFilter = this::isSearchCandidate;
|
||||||
Iterator<Archive> archives = this.archive.getNestedArchives(searchFilter, this::isNestedArchive);
|
Iterator<Archive> archives = this.archive.getNestedArchives(searchFilter,
|
||||||
|
(entry) -> isNestedArchive(entry) && !isEntryIndexed(entry));
|
||||||
if (isPostProcessingClassPathArchives()) {
|
if (isPostProcessingClassPathArchives()) {
|
||||||
archives = applyClassPathArchivePostProcessing(archives);
|
archives = applyClassPathArchivePostProcessing(archives);
|
||||||
}
|
}
|
||||||
return archives;
|
return archives;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isFolderIndexed(Archive.Entry entry) {
|
private boolean isEntryIndexed(Archive.Entry entry) {
|
||||||
if (this.classPathIndex != null) {
|
if (this.classPathIndex != null) {
|
||||||
return this.classPathIndex.containsFolder(entry.getName());
|
return this.classPathIndex.containsEntry(entry.getName());
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,7 @@ import java.io.Writer;
|
||||||
import java.net.MalformedURLException;
|
import java.net.MalformedURLException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.Enumeration;
|
import java.util.Enumeration;
|
||||||
import java.util.LinkedHashSet;
|
import java.util.LinkedHashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -52,11 +53,12 @@ public abstract class AbstractExecutableArchiveLauncherTests {
|
||||||
File tempDir;
|
File tempDir;
|
||||||
|
|
||||||
protected File createJarArchive(String name, String entryPrefix) throws IOException {
|
protected File createJarArchive(String name, String entryPrefix) throws IOException {
|
||||||
return createJarArchive(name, entryPrefix, false);
|
return createJarArchive(name, entryPrefix, false, Collections.emptyList());
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("resource")
|
@SuppressWarnings("resource")
|
||||||
protected File createJarArchive(String name, String entryPrefix, boolean indexed) throws IOException {
|
protected File createJarArchive(String name, String entryPrefix, boolean indexed, List<String> extraLibs)
|
||||||
|
throws IOException {
|
||||||
File archive = new File(this.tempDir, name);
|
File archive = new File(this.tempDir, name);
|
||||||
JarOutputStream jarOutputStream = new JarOutputStream(new FileOutputStream(archive));
|
JarOutputStream jarOutputStream = new JarOutputStream(new FileOutputStream(archive));
|
||||||
jarOutputStream.putNextEntry(new JarEntry(entryPrefix + "/"));
|
jarOutputStream.putNextEntry(new JarEntry(entryPrefix + "/"));
|
||||||
|
@ -74,6 +76,9 @@ public abstract class AbstractExecutableArchiveLauncherTests {
|
||||||
addNestedJars(entryPrefix, "/lib/foo.jar", jarOutputStream);
|
addNestedJars(entryPrefix, "/lib/foo.jar", jarOutputStream);
|
||||||
addNestedJars(entryPrefix, "/lib/bar.jar", jarOutputStream);
|
addNestedJars(entryPrefix, "/lib/bar.jar", jarOutputStream);
|
||||||
addNestedJars(entryPrefix, "/lib/baz.jar", jarOutputStream);
|
addNestedJars(entryPrefix, "/lib/baz.jar", jarOutputStream);
|
||||||
|
for (String lib : extraLibs) {
|
||||||
|
addNestedJars(entryPrefix, "/lib/" + lib, jarOutputStream);
|
||||||
|
}
|
||||||
jarOutputStream.close();
|
jarOutputStream.close();
|
||||||
return archive;
|
return archive;
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,8 @@ import java.io.File;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.net.URLClassLoader;
|
import java.net.URLClassLoader;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
@ -72,7 +74,7 @@ class JarLauncherTests extends AbstractExecutableArchiveLauncherTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void explodedJarShouldPreserveClasspathOrderWhenIndexPresent() throws Exception {
|
void explodedJarShouldPreserveClasspathOrderWhenIndexPresent() throws Exception {
|
||||||
File explodedRoot = explode(createJarArchive("archive.jar", "BOOT-INF", true));
|
File explodedRoot = explode(createJarArchive("archive.jar", "BOOT-INF", true, Collections.emptyList()));
|
||||||
JarLauncher launcher = new JarLauncher(new ExplodedArchive(explodedRoot, true));
|
JarLauncher launcher = new JarLauncher(new ExplodedArchive(explodedRoot, true));
|
||||||
Iterator<Archive> archives = launcher.getClassPathArchivesIterator();
|
Iterator<Archive> archives = launcher.getClassPathArchivesIterator();
|
||||||
URLClassLoader classLoader = (URLClassLoader) launcher.createClassLoader(archives);
|
URLClassLoader classLoader = (URLClassLoader) launcher.createClassLoader(archives);
|
||||||
|
@ -80,6 +82,19 @@ class JarLauncherTests extends AbstractExecutableArchiveLauncherTests {
|
||||||
assertThat(urls).containsExactly(getExpectedFileUrls(explodedRoot));
|
assertThat(urls).containsExactly(getExpectedFileUrls(explodedRoot));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void jarFilesPresentInBootInfLibsAndNotInClasspathIndexShouldBeAddedAfterBootInfClasses() throws Exception {
|
||||||
|
ArrayList<String> extraLibs = new ArrayList<>(Arrays.asList("extra-1.jar", "extra-2.jar"));
|
||||||
|
File explodedRoot = explode(createJarArchive("archive.jar", "BOOT-INF", true, extraLibs));
|
||||||
|
JarLauncher launcher = new JarLauncher(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) {
|
protected final URL[] getExpectedFileUrls(File explodedRoot) {
|
||||||
return getExpectedFiles(explodedRoot).stream().map(this::toUrl).toArray(URL[]::new);
|
return getExpectedFiles(explodedRoot).stream().map(this::toUrl).toArray(URL[]::new);
|
||||||
}
|
}
|
||||||
|
@ -93,4 +108,15 @@ class JarLauncherTests extends AbstractExecutableArchiveLauncherTests {
|
||||||
return expected;
|
return expected;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected final List<File> getExpectedFilesWithExtraLibs(File parent) {
|
||||||
|
List<File> expected = new ArrayList<>();
|
||||||
|
expected.add(new File(parent, "BOOT-INF/classes"));
|
||||||
|
expected.add(new File(parent, "BOOT-INF/lib/extra-1.jar"));
|
||||||
|
expected.add(new File(parent, "BOOT-INF/lib/extra-2.jar"));
|
||||||
|
expected.add(new File(parent, "BOOT-INF/lib/foo.jar"));
|
||||||
|
expected.add(new File(parent, "BOOT-INF/lib/bar.jar"));
|
||||||
|
expected.add(new File(parent, "BOOT-INF/lib/baz.jar"));
|
||||||
|
return expected;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue