Merge branch '4.0.x' into 4.1.x

Closes gh-51089
This commit is contained in:
Stéphane Nicoll
2026-07-21 15:18:23 +02:00
2 changed files with 21 additions and 24 deletions
@@ -136,8 +136,6 @@ public class PropertiesLauncher extends Launcher {
private final File homeDirectory;
private final List<String> paths;
private final Properties properties = new Properties();
public PropertiesLauncher() throws Exception {
@@ -148,7 +146,6 @@ public class PropertiesLauncher extends Launcher {
this.archive = archive;
this.homeDirectory = getHomeDirectory();
initializeProperties();
this.paths = getPaths();
this.classPathIndex = getClassPathIndex(this.archive);
}
@@ -292,11 +289,9 @@ public class PropertiesLauncher extends Launcher {
}
}
private List<String> getPaths() throws Exception {
private List<String> resolvePaths() throws Exception {
String path = getProperty(PATH);
List<String> paths = (path != null) ? parsePathsProperty(path) : Collections.emptyList();
debug.log("Nested archive paths: %s", this.paths);
return paths;
return (path != null) ? parsePathsProperty(path) : Collections.emptyList();
}
private List<String> parsePathsProperty(String commaSeparatedPaths) {
@@ -470,7 +465,9 @@ public class PropertiesLauncher extends Launcher {
@Override
protected Set<URL> getClassPathUrls() throws Exception {
Set<URL> urls = new LinkedHashSet<>();
for (String path : getPaths()) {
List<String> paths = resolvePaths();
debug.log("Nested archive paths: %s", paths);
for (String path : paths) {
path = cleanupPath(handleUrl(path));
urls.addAll(getClassPathUrlsForPath(path));
}
@@ -127,7 +127,7 @@ class PropertiesLauncherTests extends AbstractLauncherTests {
System.setProperty("loader.config.name", "foo");
this.launcher = new PropertiesLauncher();
assertThat(this.launcher.getMainClass()).isEqualTo("my.Application");
assertThat(ReflectionTestUtils.getField(this.launcher, "paths")).hasToString("[etc/]");
assertThat(resolvedPaths()).containsExactly("etc/");
}
@Test
@@ -141,14 +141,14 @@ class PropertiesLauncherTests extends AbstractLauncherTests {
void testUserSpecifiedDotPath() throws Exception {
System.setProperty("loader.path", ".");
this.launcher = new PropertiesLauncher();
assertThat(ReflectionTestUtils.getField(this.launcher, "paths")).hasToString("[.]");
assertThat(resolvedPaths()).containsExactly(".");
}
@Test
void testUserSpecifiedSlashPath() throws Exception {
System.setProperty("loader.path", "jars/");
this.launcher = new PropertiesLauncher();
assertThat(ReflectionTestUtils.getField(this.launcher, "paths")).hasToString("[jars/]");
assertThat(resolvedPaths()).containsExactly("jars/");
Set<URL> urls = this.launcher.getClassPathUrls();
assertThat(urls).areExactly(1, endingWith("app.jar"));
}
@@ -158,7 +158,7 @@ class PropertiesLauncherTests extends AbstractLauncherTests {
System.setProperty("loader.path", "jars/*");
System.setProperty("loader.main", "demo.Application");
this.launcher = new PropertiesLauncher();
assertThat(ReflectionTestUtils.getField(this.launcher, "paths")).hasToString("[jars/]");
assertThat(resolvedPaths()).containsExactly("jars/");
this.launcher.launch(new String[0]);
waitFor("Hello World");
}
@@ -168,7 +168,7 @@ class PropertiesLauncherTests extends AbstractLauncherTests {
System.setProperty("loader.path", "jars/app.jar");
System.setProperty("loader.main", "demo.Application");
this.launcher = new PropertiesLauncher();
assertThat(ReflectionTestUtils.getField(this.launcher, "paths")).hasToString("[jars/app.jar]");
assertThat(resolvedPaths()).containsExactly("jars/app.jar");
this.launcher.launch(new String[0]);
waitFor("Hello World");
}
@@ -177,8 +177,7 @@ class PropertiesLauncherTests extends AbstractLauncherTests {
void testUserSpecifiedRootOfJarPath() throws Exception {
System.setProperty("loader.path", "jar:file:./src/test/resources/nested-jars/app.jar!/");
this.launcher = new PropertiesLauncher();
assertThat(ReflectionTestUtils.getField(this.launcher, "paths"))
.hasToString("[jar:file:./src/test/resources/nested-jars/app.jar!/]");
assertThat(resolvedPaths()).containsExactly("jar:file:./src/test/resources/nested-jars/app.jar!/");
Set<URL> urls = this.launcher.getClassPathUrls();
assertThat(urls).areExactly(1, endingWith("foo.jar!/"));
assertThat(urls).areExactly(1, endingWith("app.jar!/"));
@@ -216,8 +215,7 @@ class PropertiesLauncherTests extends AbstractLauncherTests {
System.setProperty("loader.path", "nested-jars/nested-jar-app.jar!/BOOT-INF/classes/");
System.setProperty("loader.main", "demo.Application");
this.launcher = new PropertiesLauncher();
assertThat(ReflectionTestUtils.getField(this.launcher, "paths"))
.hasToString("[nested-jars/nested-jar-app.jar!/BOOT-INF/classes/]");
assertThat(resolvedPaths()).containsExactly("nested-jars/nested-jar-app.jar!/BOOT-INF/classes/");
this.launcher.launch(new String[0]);
waitFor("Hello World");
}
@@ -236,7 +234,7 @@ class PropertiesLauncherTests extends AbstractLauncherTests {
System.setProperty("loader.path", "./jars/app.jar");
System.setProperty("loader.main", "demo.Application");
this.launcher = new PropertiesLauncher();
assertThat(ReflectionTestUtils.getField(this.launcher, "paths")).hasToString("[jars/app.jar]");
assertThat(resolvedPaths()).containsExactly("jars/app.jar");
this.launcher.launch(new String[0]);
waitFor("Hello World");
}
@@ -246,7 +244,7 @@ class PropertiesLauncherTests extends AbstractLauncherTests {
System.setProperty("loader.path", "jars/app.jar");
System.setProperty("loader.classLoader", URLClassLoader.class.getName());
this.launcher = new PropertiesLauncher();
assertThat(ReflectionTestUtils.getField(this.launcher, "paths")).hasToString("[jars/app.jar]");
assertThat(resolvedPaths()).containsExactly("jars/app.jar");
this.launcher.launch(new String[0]);
waitFor("Hello World");
}
@@ -256,8 +254,7 @@ class PropertiesLauncherTests extends AbstractLauncherTests {
System.setProperty("loader.path", "more-jars/app.jar,jars/app.jar");
System.setProperty("loader.classLoader", URLClassLoader.class.getName());
this.launcher = new PropertiesLauncher();
assertThat(ReflectionTestUtils.getField(this.launcher, "paths"))
.hasToString("[more-jars/app.jar, jars/app.jar]");
assertThat(resolvedPaths()).containsExactly("more-jars/app.jar", "jars/app.jar");
this.launcher.launch(new String[0]);
waitFor("Hello Other World");
}
@@ -309,7 +306,7 @@ class PropertiesLauncherTests extends AbstractLauncherTests {
void testArgsEnhanced() throws Exception {
System.setProperty("loader.args", "foo");
this.launcher = new PropertiesLauncher();
assertThat(Arrays.asList(this.launcher.getArgs("bar"))).hasToString("[foo, bar]");
assertThat(Arrays.asList(this.launcher.getArgs("bar"))).containsExactly("foo", "bar");
}
@Test
@@ -325,8 +322,7 @@ class PropertiesLauncherTests extends AbstractLauncherTests {
manifest.write(manifestStream);
}
this.launcher = new PropertiesLauncher();
assertThat((List<String>) ReflectionTestUtils.getField(this.launcher, "paths")).containsExactly("/foo.jar",
"/bar/");
assertThat(resolvedPaths()).containsExactly("/foo.jar", "/bar/");
}
@Test
@@ -447,6 +443,10 @@ class PropertiesLauncherTests extends AbstractLauncherTests {
return expected;
}
private List<String> resolvedPaths() {
return ReflectionTestUtils.invokeMethod(this.launcher, "resolvePaths");
}
private Condition<URL> endingWith(String value) {
return new Condition<>() {