Merge branch '3.2.x' into 3.3.x
Closes gh-41970
This commit is contained in:
@@ -16,16 +16,12 @@
|
||||
|
||||
package org.springframework.boot.loader.launch;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Set;
|
||||
import java.util.jar.Attributes;
|
||||
import java.util.jar.Manifest;
|
||||
|
||||
import org.springframework.boot.loader.launch.Archive.Entry;
|
||||
|
||||
/**
|
||||
* Base class for a {@link Launcher} backed by an executable archive.
|
||||
*
|
||||
@@ -41,14 +37,8 @@ public abstract class ExecutableArchiveLauncher extends Launcher {
|
||||
|
||||
private static final String START_CLASS_ATTRIBUTE = "Start-Class";
|
||||
|
||||
protected static final String BOOT_CLASSPATH_INDEX_ATTRIBUTE = "Spring-Boot-Classpath-Index";
|
||||
|
||||
protected static final String DEFAULT_CLASSPATH_INDEX_FILE_NAME = "classpath.idx";
|
||||
|
||||
private final Archive archive;
|
||||
|
||||
private final ClassPathIndexFile classPathIndex;
|
||||
|
||||
public ExecutableArchiveLauncher() throws Exception {
|
||||
this(Archive.create(Launcher.class));
|
||||
}
|
||||
@@ -58,21 +48,6 @@ public abstract class ExecutableArchiveLauncher extends Launcher {
|
||||
this.classPathIndex = getClassPathIndex(this.archive);
|
||||
}
|
||||
|
||||
ClassPathIndexFile getClassPathIndex(Archive archive) throws IOException {
|
||||
if (!archive.isExploded()) {
|
||||
return null; // Regular archives already have a defined order
|
||||
}
|
||||
String location = getClassPathIndexFileLocation(archive);
|
||||
return ClassPathIndexFile.loadIfPossible(archive.getRootDirectory(), location);
|
||||
}
|
||||
|
||||
private String getClassPathIndexFileLocation(Archive archive) throws IOException {
|
||||
Manifest manifest = archive.getManifest();
|
||||
Attributes attributes = (manifest != null) ? manifest.getMainAttributes() : null;
|
||||
String location = (attributes != null) ? attributes.getValue(BOOT_CLASSPATH_INDEX_ATTRIBUTE) : null;
|
||||
return (location != null) ? location : getEntryPathPrefix() + DEFAULT_CLASSPATH_INDEX_FILE_NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ClassLoader createClassLoader(Collection<URL> urls) throws Exception {
|
||||
if (this.classPathIndex != null) {
|
||||
@@ -102,13 +77,6 @@ public abstract class ExecutableArchiveLauncher extends Launcher {
|
||||
return this.archive.getClassPathUrls(this::isIncludedOnClassPathAndNotIndexed, this::isSearchedDirectory);
|
||||
}
|
||||
|
||||
private boolean isIncludedOnClassPathAndNotIndexed(Entry entry) {
|
||||
if (!isIncludedOnClassPath(entry)) {
|
||||
return false;
|
||||
}
|
||||
return (this.classPathIndex == null) || !this.classPathIndex.containsEntry(entry.name());
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the specified directory entry is a candidate for further searching.
|
||||
* @param entry the entry to check
|
||||
@@ -119,18 +87,4 @@ public abstract class ExecutableArchiveLauncher extends Launcher {
|
||||
&& !isIncludedOnClassPath(entry);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the specified entry is a nested item that should be added to the
|
||||
* classpath.
|
||||
* @param entry the entry to check
|
||||
* @return {@code true} if the entry is a nested item (jar or directory)
|
||||
*/
|
||||
protected abstract boolean isIncludedOnClassPath(Archive.Entry entry);
|
||||
|
||||
/**
|
||||
* Return the path prefix for relevant entries in the archive.
|
||||
* @return the entry path prefix
|
||||
*/
|
||||
protected abstract String getEntryPathPrefix();
|
||||
|
||||
}
|
||||
|
||||
@@ -36,24 +36,6 @@ public class JarLauncher extends ExecutableArchiveLauncher {
|
||||
super(archive);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isIncludedOnClassPath(Archive.Entry entry) {
|
||||
return isLibraryFileOrClassesDirectory(entry);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getEntryPathPrefix() {
|
||||
return "BOOT-INF/";
|
||||
}
|
||||
|
||||
static boolean isLibraryFileOrClassesDirectory(Archive.Entry entry) {
|
||||
String name = entry.name();
|
||||
if (entry.isDirectory()) {
|
||||
return name.equals("BOOT-INF/classes/");
|
||||
}
|
||||
return name.startsWith("BOOT-INF/lib/");
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
new JarLauncher().launch(args);
|
||||
}
|
||||
|
||||
@@ -16,12 +16,16 @@
|
||||
|
||||
package org.springframework.boot.loader.launch;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.URL;
|
||||
import java.util.Collection;
|
||||
import java.util.Set;
|
||||
import java.util.jar.Attributes;
|
||||
import java.util.jar.Manifest;
|
||||
|
||||
import org.springframework.boot.loader.launch.Archive.Entry;
|
||||
import org.springframework.boot.loader.net.protocol.Handlers;
|
||||
|
||||
/**
|
||||
@@ -30,12 +34,19 @@ import org.springframework.boot.loader.net.protocol.Handlers;
|
||||
*
|
||||
* @author Phillip Webb
|
||||
* @author Dave Syer
|
||||
* @author Scott Frederick
|
||||
* @since 3.2.0
|
||||
*/
|
||||
public abstract class Launcher {
|
||||
|
||||
private static final String JAR_MODE_RUNNER_CLASS_NAME = JarModeRunner.class.getName();
|
||||
|
||||
protected static final String BOOT_CLASSPATH_INDEX_ATTRIBUTE = "Spring-Boot-Classpath-Index";
|
||||
|
||||
protected static final String DEFAULT_CLASSPATH_INDEX_FILE_NAME = "classpath.idx";
|
||||
|
||||
protected ClassPathIndexFile classPathIndex;
|
||||
|
||||
/**
|
||||
* Launch the application. This method is the initial entry point that should be
|
||||
* called by a subclass {@code public static void main(String[] args)} method.
|
||||
@@ -102,6 +113,21 @@ public abstract class Launcher {
|
||||
return (archive != null) && archive.isExploded();
|
||||
}
|
||||
|
||||
ClassPathIndexFile getClassPathIndex(Archive archive) throws IOException {
|
||||
if (!archive.isExploded()) {
|
||||
return null; // Regular archives already have a defined order
|
||||
}
|
||||
String location = getClassPathIndexFileLocation(archive);
|
||||
return ClassPathIndexFile.loadIfPossible(archive.getRootDirectory(), location);
|
||||
}
|
||||
|
||||
private String getClassPathIndexFileLocation(Archive archive) throws IOException {
|
||||
Manifest manifest = archive.getManifest();
|
||||
Attributes attributes = (manifest != null) ? manifest.getMainAttributes() : null;
|
||||
String location = (attributes != null) ? attributes.getValue(BOOT_CLASSPATH_INDEX_ATTRIBUTE) : null;
|
||||
return (location != null) ? location : getEntryPathPrefix() + DEFAULT_CLASSPATH_INDEX_FILE_NAME;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the archive being launched or {@code null} if there is no archive.
|
||||
* @return the launched archive
|
||||
@@ -122,4 +148,37 @@ public abstract class Launcher {
|
||||
*/
|
||||
protected abstract Set<URL> getClassPathUrls() throws Exception;
|
||||
|
||||
/**
|
||||
* Return the path prefix for relevant entries in the archive.
|
||||
* @return the entry path prefix
|
||||
*/
|
||||
protected String getEntryPathPrefix() {
|
||||
return "BOOT-INF/";
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the specified entry is a nested item that should be added to the
|
||||
* classpath.
|
||||
* @param entry the entry to check
|
||||
* @return {@code true} if the entry is a nested item (jar or directory)
|
||||
*/
|
||||
protected boolean isIncludedOnClassPath(Archive.Entry entry) {
|
||||
return isLibraryFileOrClassesDirectory(entry);
|
||||
}
|
||||
|
||||
protected boolean isLibraryFileOrClassesDirectory(Archive.Entry entry) {
|
||||
String name = entry.name();
|
||||
if (entry.isDirectory()) {
|
||||
return name.equals("BOOT-INF/classes/");
|
||||
}
|
||||
return name.startsWith("BOOT-INF/lib/");
|
||||
}
|
||||
|
||||
protected boolean isIncludedOnClassPathAndNotIndexed(Entry entry) {
|
||||
if (!isIncludedOnClassPath(entry)) {
|
||||
return false;
|
||||
}
|
||||
return (this.classPathIndex == null) || !this.classPathIndex.containsEntry(entry.name());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -70,6 +70,7 @@ import org.springframework.boot.loader.net.protocol.jar.JarUrl;
|
||||
* @author Janne Valkealahti
|
||||
* @author Andy Wilkinson
|
||||
* @author Phillip Webb
|
||||
* @author Scott Frederick
|
||||
* @since 3.2.0
|
||||
*/
|
||||
public class PropertiesLauncher extends Launcher {
|
||||
@@ -148,6 +149,7 @@ public class PropertiesLauncher extends Launcher {
|
||||
this.homeDirectory = getHomeDirectory();
|
||||
initializeProperties();
|
||||
this.paths = getPaths();
|
||||
this.classPathIndex = getClassPathIndex(this.archive);
|
||||
}
|
||||
|
||||
protected File getHomeDirectory() throws Exception {
|
||||
@@ -330,6 +332,10 @@ public class PropertiesLauncher extends Launcher {
|
||||
@Override
|
||||
protected ClassLoader createClassLoader(Collection<URL> urls) throws Exception {
|
||||
String loaderClassName = getProperty("loader.classLoader");
|
||||
if (this.classPathIndex != null) {
|
||||
urls = new ArrayList<>(urls);
|
||||
urls.addAll(this.classPathIndex.getUrls());
|
||||
}
|
||||
if (loaderClassName == null) {
|
||||
return super.createClassLoader(urls);
|
||||
}
|
||||
@@ -537,9 +543,9 @@ public class PropertiesLauncher extends Launcher {
|
||||
}
|
||||
}
|
||||
|
||||
private Set<URL> getClassPathUrlsForRoot() throws IOException {
|
||||
private Set<URL> getClassPathUrlsForRoot() throws Exception {
|
||||
debug.log("Adding classpath entries from root archive %s", this.archive);
|
||||
return this.archive.getClassPathUrls(JarLauncher::isLibraryFileOrClassesDirectory);
|
||||
return this.archive.getClassPathUrls(this::isIncludedOnClassPathAndNotIndexed, Archive.ALL_ENTRIES);
|
||||
}
|
||||
|
||||
private Predicate<Entry> includeByPrefix(String prefix) {
|
||||
|
||||
@@ -35,17 +35,13 @@ public class WarLauncher extends ExecutableArchiveLauncher {
|
||||
super(archive);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isIncludedOnClassPath(Archive.Entry entry) {
|
||||
return isLibraryFileOrClassesDirectory(entry);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getEntryPathPrefix() {
|
||||
return "WEB-INF/";
|
||||
}
|
||||
|
||||
static boolean isLibraryFileOrClassesDirectory(Archive.Entry entry) {
|
||||
@Override
|
||||
protected boolean isLibraryFileOrClassesDirectory(Archive.Entry entry) {
|
||||
String name = entry.name();
|
||||
if (entry.isDirectory()) {
|
||||
return name.equals("WEB-INF/classes/");
|
||||
|
||||
Reference in New Issue
Block a user