Improve handling of loader.path in PropertiesLauncher
Previously, if loader.path directly specified a jar file that contained nested archives (.zip or .jar), launching would fail unless those nested archives were uncompressed. However, if loader.path specified a directory that contained such a jar file the launch would succeed. This was because the nested archives within the jar were ignored. This commit updates PropertiesLauncher so that its behaviour in the scenarios described above is consistent by not looking for archives nested with a jar that’s be specified on loader.path. The javadoc for loader.path has also been updated to make it clear that loader.path can points to directories or jar files, bringing it into line with the reference guide. Closes gh-3701
This commit is contained in:
parent
313b6f6451
commit
68b83a8f00
|
|
@ -55,9 +55,10 @@ import org.springframework.boot.loader.util.SystemPropertyUtils;
|
||||||
* extracts optional values (which can also be provided overridden as System properties in
|
* extracts optional values (which can also be provided overridden as System properties in
|
||||||
* case the file doesn't exist):
|
* case the file doesn't exist):
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>{@code loader.path}: a comma-separated list of directories to append to the
|
* <li>{@code loader.path}: a comma-separated list of directories (containing file
|
||||||
* classpath (containing file resources and/or nested archives in *.jar or *.zip).
|
* resources and/or nested archives in *.jar or *.zip or archives) or archives to append
|
||||||
* Defaults to {@code BOOT-INF/classes,BOOT-INF/lib} in your application archive</li>
|
* to the classpath. {@code BOOT-INF/classes,BOOT-INF/lib} in the application archive are
|
||||||
|
* always used</li>
|
||||||
* <li>{@code loader.main}: the main method to delegate execution to once the class loader
|
* <li>{@code loader.main}: the main method to delegate execution to once the class loader
|
||||||
* is set up. No default, but will fall back to looking for a {@code Start-Class} in a
|
* is set up. No default, but will fall back to looking for a {@code Start-Class} in a
|
||||||
* {@code MANIFEST.MF}, if there is one in <code>${loader.home}/META-INF</code>.</li>
|
* {@code MANIFEST.MF}, if there is one in <code>${loader.home}/META-INF</code>.</li>
|
||||||
|
|
@ -78,9 +79,9 @@ public class PropertiesLauncher extends Launcher {
|
||||||
public static final String MAIN = "loader.main";
|
public static final String MAIN = "loader.main";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Properties key for classpath entries (directories possibly containing jars).
|
* Properties key for classpath entries (directories possibly containing jars or
|
||||||
* Defaults to "lib/" (relative to {@link #HOME loader home directory}). Multiple
|
* jars). Multiple entries can be specified using a comma-separated list. {@code
|
||||||
* entries can be specified using a comma-separated list.
|
* BOOT-INF/classes,BOOT-INF/lib} in the application archive are always used.
|
||||||
*/
|
*/
|
||||||
public static final String PATH = "loader.path";
|
public static final String PATH = "loader.path";
|
||||||
|
|
||||||
|
|
@ -407,11 +408,16 @@ public class PropertiesLauncher extends Launcher {
|
||||||
List<Archive> lib = new ArrayList<Archive>();
|
List<Archive> lib = new ArrayList<Archive>();
|
||||||
for (String path : this.paths) {
|
for (String path : this.paths) {
|
||||||
for (Archive archive : getClassPathArchives(path)) {
|
for (Archive archive : getClassPathArchives(path)) {
|
||||||
|
if (archive instanceof ExplodedArchive) {
|
||||||
List<Archive> nested = new ArrayList<Archive>(
|
List<Archive> nested = new ArrayList<Archive>(
|
||||||
archive.getNestedArchives(new ArchiveEntryFilter()));
|
archive.getNestedArchives(new ArchiveEntryFilter()));
|
||||||
nested.add(0, archive);
|
nested.add(0, archive);
|
||||||
lib.addAll(nested);
|
lib.addAll(nested);
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
lib.add(archive);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
addNestedEntries(lib);
|
addNestedEntries(lib);
|
||||||
return lib;
|
return lib;
|
||||||
|
|
|
||||||
|
|
@ -115,6 +115,25 @@ public class PropertiesLauncherTests {
|
||||||
waitFor("Hello World");
|
waitFor("Hello World");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUserSpecifiedJarFileWithNestedArchives() throws Exception {
|
||||||
|
System.setProperty("loader.path", "nested-jars/app.jar");
|
||||||
|
System.setProperty("loader.main", "demo.Application");
|
||||||
|
PropertiesLauncher launcher = new PropertiesLauncher();
|
||||||
|
launcher.launch(new String[0]);
|
||||||
|
waitFor("Hello World");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUserSpecifiedDirectoryContainingJarFileWithNestedArchives()
|
||||||
|
throws Exception {
|
||||||
|
System.setProperty("loader.path", "nested-jars");
|
||||||
|
System.setProperty("loader.main", "demo.Application");
|
||||||
|
PropertiesLauncher launcher = new PropertiesLauncher();
|
||||||
|
launcher.launch(new String[0]);
|
||||||
|
waitFor("Hello World");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testUserSpecifiedJarPathWithDot() throws Exception {
|
public void testUserSpecifiedJarPathWithDot() throws Exception {
|
||||||
System.setProperty("loader.path", "./jars/app.jar");
|
System.setProperty("loader.path", "./jars/app.jar");
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue