Support generation and loading of layered jars

Support an alternative fat jar format that is more amenable to Docker
image layers.

The new format arranges files in the following structure:

	BOOT-INF/
	  layers/
	    <layer-name #1>
	      /classes
	      /lib
	    <layer-name #2>
	      /classes
	      /lib

The `BOOT-INF/layers.idx` file provides the names of the layers and the
order in which they should be added (starting with the least changed).

The `JarLauncher` class can load layered jars in both fat and exploded
forms.

Closes gh-19767

Co-authored-by: Phillip Webb <pwebb@pivotal.io>
This commit is contained in:
Madhura Bhave
2020-01-15 21:21:56 -08:00
committed by Phillip Webb
parent 45b1ab46c3
commit e9d61bac75
11 changed files with 614 additions and 7 deletions

View File

@@ -19,6 +19,7 @@ package org.springframework.boot.loader;
import java.io.IOException;
import java.util.jar.Attributes;
import java.util.jar.Manifest;
import java.util.regex.Pattern;
import org.springframework.boot.loader.archive.Archive;
import org.springframework.boot.loader.archive.Archive.EntryFilter;
@@ -36,13 +37,17 @@ import org.springframework.boot.loader.archive.ExplodedArchive;
*/
public class JarLauncher extends ExecutableArchiveLauncher {
private static final Pattern CLASSES_PATTERN = Pattern.compile("BOOT-INF\\/(layers\\/.*\\/)?classes/");
private static final Pattern LIBS_PATTERN = Pattern.compile("BOOT-INF\\/(layers\\/.*\\/)?lib\\/.+");
private static final String DEFAULT_CLASSPATH_INDEX_LOCATION = "BOOT-INF/classpath.idx";
static final EntryFilter NESTED_ARCHIVE_ENTRY_FILTER = (entry) -> {
if (entry.isDirectory()) {
return entry.getName().equals("BOOT-INF/classes/");
return CLASSES_PATTERN.matcher(entry.getName()).matches();
}
return entry.getName().startsWith("BOOT-INF/lib/");
return LIBS_PATTERN.matcher(entry.getName()).matches();
};
public JarLauncher() {