Optimize JarLauncher when used with exploded jar
- Previously, we would create a JarFileArchive for all nested jars. This was an additional overhead. We only need to create a JarFileArchive for jars that can have nested jars in them. For all other jars we only need the URL to build the classpath. - While iterating over nested entries in the exploded jar, we only need to look at BOOT-INF and we can skip any entry that does not match that. Closes gh-16655 Co-authored-by: Phillip Webb <pwebb@pivotal.io>
This commit is contained in:
@@ -20,6 +20,7 @@ import java.io.File;
|
||||
import java.net.URL;
|
||||
import java.util.List;
|
||||
|
||||
import org.codehaus.plexus.util.CollectionUtils;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.loader.archive.Archive;
|
||||
@@ -39,7 +40,7 @@ class JarLauncherTests extends AbstractExecutableArchiveLauncherTests {
|
||||
void explodedJarHasOnlyBootInfClassesAndContentsOfBootInfLibOnClasspath() throws Exception {
|
||||
File explodedRoot = explode(createJarArchive("archive.jar", "BOOT-INF"));
|
||||
JarLauncher launcher = new JarLauncher(new ExplodedArchive(explodedRoot, true));
|
||||
List<Archive> archives = launcher.getClassPathArchives();
|
||||
List<Archive> archives = CollectionUtils.iteratorToList(launcher.getClassPathArchivesIterator());
|
||||
assertThat(archives).hasSize(2);
|
||||
assertThat(getUrls(archives)).containsOnly(new File(explodedRoot, "BOOT-INF/classes").toURI().toURL(),
|
||||
new File(explodedRoot, "BOOT-INF/lib/foo.jar").toURI().toURL());
|
||||
@@ -53,7 +54,7 @@ class JarLauncherTests extends AbstractExecutableArchiveLauncherTests {
|
||||
File jarRoot = createJarArchive("archive.jar", "BOOT-INF");
|
||||
try (JarFileArchive archive = new JarFileArchive(jarRoot)) {
|
||||
JarLauncher launcher = new JarLauncher(archive);
|
||||
List<Archive> classPathArchives = launcher.getClassPathArchives();
|
||||
List<Archive> classPathArchives = CollectionUtils.iteratorToList(launcher.getClassPathArchivesIterator());
|
||||
assertThat(classPathArchives).hasSize(2);
|
||||
assertThat(getUrls(classPathArchives)).containsOnly(
|
||||
new URL("jar:" + jarRoot.toURI().toURL() + "!/BOOT-INF/classes!/"),
|
||||
|
||||
@@ -30,6 +30,7 @@ import java.util.jar.Manifest;
|
||||
|
||||
import org.assertj.core.api.Condition;
|
||||
import org.awaitility.Awaitility;
|
||||
import org.codehaus.plexus.util.CollectionUtils;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@@ -139,7 +140,7 @@ class PropertiesLauncherTests {
|
||||
System.setProperty("loader.path", "jars/");
|
||||
PropertiesLauncher launcher = new PropertiesLauncher();
|
||||
assertThat(ReflectionTestUtils.getField(launcher, "paths").toString()).isEqualTo("[jars/]");
|
||||
List<Archive> archives = launcher.getClassPathArchives();
|
||||
List<Archive> archives = CollectionUtils.iteratorToList(launcher.getClassPathArchivesIterator());
|
||||
assertThat(archives).areExactly(1, endingWith("app.jar"));
|
||||
}
|
||||
|
||||
@@ -169,7 +170,7 @@ class PropertiesLauncherTests {
|
||||
PropertiesLauncher launcher = new PropertiesLauncher();
|
||||
assertThat(ReflectionTestUtils.getField(launcher, "paths").toString())
|
||||
.isEqualTo("[jar:file:./src/test/resources/nested-jars/app.jar!/]");
|
||||
List<Archive> archives = launcher.getClassPathArchives();
|
||||
List<Archive> archives = CollectionUtils.iteratorToList(launcher.getClassPathArchivesIterator());
|
||||
assertThat(archives).areExactly(1, endingWith("foo.jar!/"));
|
||||
assertThat(archives).areExactly(1, endingWith("app.jar"));
|
||||
}
|
||||
@@ -178,7 +179,7 @@ class PropertiesLauncherTests {
|
||||
void testUserSpecifiedRootOfJarPathWithDot() throws Exception {
|
||||
System.setProperty("loader.path", "nested-jars/app.jar!/./");
|
||||
PropertiesLauncher launcher = new PropertiesLauncher();
|
||||
List<Archive> archives = launcher.getClassPathArchives();
|
||||
List<Archive> archives = CollectionUtils.iteratorToList(launcher.getClassPathArchivesIterator());
|
||||
assertThat(archives).areExactly(1, endingWith("foo.jar!/"));
|
||||
assertThat(archives).areExactly(1, endingWith("app.jar"));
|
||||
}
|
||||
@@ -187,7 +188,7 @@ class PropertiesLauncherTests {
|
||||
void testUserSpecifiedRootOfJarPathWithDotAndJarPrefix() throws Exception {
|
||||
System.setProperty("loader.path", "jar:file:./src/test/resources/nested-jars/app.jar!/./");
|
||||
PropertiesLauncher launcher = new PropertiesLauncher();
|
||||
List<Archive> archives = launcher.getClassPathArchives();
|
||||
List<Archive> archives = CollectionUtils.iteratorToList(launcher.getClassPathArchivesIterator());
|
||||
assertThat(archives).areExactly(1, endingWith("foo.jar!/"));
|
||||
}
|
||||
|
||||
@@ -196,7 +197,7 @@ class PropertiesLauncherTests {
|
||||
System.setProperty("loader.path", "nested-jars/app.jar");
|
||||
System.setProperty("loader.main", "demo.Application");
|
||||
PropertiesLauncher launcher = new PropertiesLauncher();
|
||||
List<Archive> archives = launcher.getClassPathArchives();
|
||||
List<Archive> archives = CollectionUtils.iteratorToList(launcher.getClassPathArchivesIterator());
|
||||
assertThat(archives).areExactly(1, endingWith("foo.jar!/"));
|
||||
assertThat(archives).areExactly(1, endingWith("app.jar"));
|
||||
}
|
||||
@@ -206,7 +207,7 @@ class PropertiesLauncherTests {
|
||||
System.setProperty("loader.path", "nested-jars/app.jar!/foo.jar");
|
||||
System.setProperty("loader.main", "demo.Application");
|
||||
PropertiesLauncher launcher = new PropertiesLauncher();
|
||||
List<Archive> archives = launcher.getClassPathArchives();
|
||||
List<Archive> archives = CollectionUtils.iteratorToList(launcher.getClassPathArchivesIterator());
|
||||
assertThat(archives).hasSize(1).areExactly(1, endingWith("foo.jar!/"));
|
||||
}
|
||||
|
||||
@@ -335,7 +336,7 @@ class PropertiesLauncherTests {
|
||||
loaderPath.mkdir();
|
||||
System.setProperty("loader.path", loaderPath.toURI().toURL().toString());
|
||||
PropertiesLauncher launcher = new PropertiesLauncher();
|
||||
List<Archive> archives = launcher.getClassPathArchives();
|
||||
List<Archive> archives = CollectionUtils.iteratorToList(launcher.getClassPathArchivesIterator());
|
||||
assertThat(archives.size()).isEqualTo(1);
|
||||
File archiveRoot = (File) ReflectionTestUtils.getField(archives.get(0), "root");
|
||||
assertThat(archiveRoot).isEqualTo(loaderPath);
|
||||
|
||||
@@ -20,6 +20,7 @@ import java.io.File;
|
||||
import java.net.URL;
|
||||
import java.util.List;
|
||||
|
||||
import org.codehaus.plexus.util.CollectionUtils;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.loader.archive.Archive;
|
||||
@@ -39,7 +40,7 @@ class WarLauncherTests extends AbstractExecutableArchiveLauncherTests {
|
||||
void explodedWarHasOnlyWebInfClassesAndContentsOfWebInfLibOnClasspath() throws Exception {
|
||||
File explodedRoot = explode(createJarArchive("archive.war", "WEB-INF"));
|
||||
WarLauncher launcher = new WarLauncher(new ExplodedArchive(explodedRoot, true));
|
||||
List<Archive> archives = launcher.getClassPathArchives();
|
||||
List<Archive> archives = CollectionUtils.iteratorToList(launcher.getClassPathArchivesIterator());
|
||||
assertThat(archives).hasSize(2);
|
||||
assertThat(getUrls(archives)).containsOnly(new File(explodedRoot, "WEB-INF/classes").toURI().toURL(),
|
||||
new File(explodedRoot, "WEB-INF/lib/foo.jar").toURI().toURL());
|
||||
@@ -53,7 +54,7 @@ class WarLauncherTests extends AbstractExecutableArchiveLauncherTests {
|
||||
File jarRoot = createJarArchive("archive.war", "WEB-INF");
|
||||
try (JarFileArchive archive = new JarFileArchive(jarRoot)) {
|
||||
WarLauncher launcher = new WarLauncher(archive);
|
||||
List<Archive> classPathArchives = launcher.getClassPathArchives();
|
||||
List<Archive> classPathArchives = CollectionUtils.iteratorToList(launcher.getClassPathArchivesIterator());
|
||||
assertThat(classPathArchives).hasSize(2);
|
||||
assertThat(getUrls(classPathArchives)).containsOnly(
|
||||
new URL("jar:" + jarRoot.toURI().toURL() + "!/WEB-INF/classes!/"),
|
||||
|
||||
@@ -74,7 +74,6 @@ class ExplodedArchiveTests {
|
||||
private void createArchive(String folderName) throws Exception {
|
||||
File file = new File(this.tempDir, "test.jar");
|
||||
TestJarCreator.createTestJar(file);
|
||||
|
||||
this.rootFolder = (StringUtils.hasText(folderName) ? new File(this.tempDir, folderName)
|
||||
: new File(this.tempDir, UUID.randomUUID().toString()));
|
||||
JarFile jarFile = new JarFile(file);
|
||||
@@ -102,7 +101,7 @@ class ExplodedArchiveTests {
|
||||
@Test
|
||||
void getEntries() {
|
||||
Map<String, Archive.Entry> entries = getEntriesMap(this.archive);
|
||||
assertThat(entries.size()).isEqualTo(12);
|
||||
assertThat(entries).hasSize(12);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -121,7 +120,7 @@ class ExplodedArchiveTests {
|
||||
Entry entry = getEntriesMap(this.archive).get("nested.jar");
|
||||
Archive nested = this.archive.getNestedArchive(entry);
|
||||
assertThat(nested.getUrl().toString()).isEqualTo(this.rootFolder.toURI() + "nested.jar");
|
||||
((JarFileArchive) nested).close();
|
||||
nested.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
Reference in New Issue
Block a user