Don't write the default loader classes when a custom launcher is used
This commit is contained in:
@@ -17,6 +17,7 @@
|
||||
package org.springframework.boot.gradle.bundling;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
@@ -41,19 +42,30 @@ import org.gradle.api.tasks.util.PatternSet;
|
||||
*/
|
||||
class BootArchiveSupport {
|
||||
|
||||
private static final Set<String> DEFAULT_LAUNCHER_CLASSES;
|
||||
|
||||
static {
|
||||
Set<String> defaultLauncherClasses = new HashSet<String>();
|
||||
defaultLauncherClasses.add("org.springframework.boot.loader.JarLauncher");
|
||||
defaultLauncherClasses.add("org.springframework.boot.loader.PropertiesLauncher");
|
||||
defaultLauncherClasses.add("org.springframework.boot.loader.WarLauncher");
|
||||
DEFAULT_LAUNCHER_CLASSES = Collections.unmodifiableSet(defaultLauncherClasses);
|
||||
}
|
||||
|
||||
private final PatternSet requiresUnpack = new PatternSet();
|
||||
|
||||
private final Set<String> storedPathPrefixes;
|
||||
|
||||
private final PatternSet exclusions = new PatternSet();
|
||||
|
||||
private String loaderMainClass;
|
||||
private final String loaderMainClass;
|
||||
|
||||
private LaunchScriptConfiguration launchScript = new LaunchScriptConfiguration();
|
||||
|
||||
private boolean excludeDevtools = true;
|
||||
|
||||
BootArchiveSupport(String... storedPathPrefixes) {
|
||||
BootArchiveSupport(String loaderMainClass, String... storedPathPrefixes) {
|
||||
this.loaderMainClass = loaderMainClass;
|
||||
this.storedPathPrefixes = new HashSet<>(Arrays.asList(storedPathPrefixes));
|
||||
this.requiresUnpack.include(Specs.satisfyNone());
|
||||
configureExclusions();
|
||||
@@ -67,21 +79,18 @@ class BootArchiveSupport {
|
||||
|
||||
CopyAction createCopyAction(Jar jar) {
|
||||
CopyAction copyAction = new BootZipCopyAction(jar.getArchivePath(),
|
||||
jar.isPreserveFileTimestamps(), this.requiresUnpack.getAsSpec(),
|
||||
this.exclusions.getAsExcludeSpec(), this.launchScript,
|
||||
this.storedPathPrefixes);
|
||||
jar.isPreserveFileTimestamps(), isUsingDefaultLoader(jar),
|
||||
this.requiresUnpack.getAsSpec(), this.exclusions.getAsExcludeSpec(),
|
||||
this.launchScript, this.storedPathPrefixes);
|
||||
if (!jar.isReproducibleFileOrder()) {
|
||||
return copyAction;
|
||||
}
|
||||
return new ReproducibleOrderingCopyAction(copyAction);
|
||||
}
|
||||
|
||||
String getLoaderMainClass() {
|
||||
return this.loaderMainClass;
|
||||
}
|
||||
|
||||
void setLoaderMainClass(String loaderMainClass) {
|
||||
this.loaderMainClass = loaderMainClass;
|
||||
private boolean isUsingDefaultLoader(Jar jar) {
|
||||
return DEFAULT_LAUNCHER_CLASSES
|
||||
.contains(jar.getManifest().getAttributes().get("Main-Class"));
|
||||
}
|
||||
|
||||
LaunchScriptConfiguration getLaunchScript() {
|
||||
|
||||
@@ -35,14 +35,14 @@ import org.gradle.api.tasks.bundling.Jar;
|
||||
*/
|
||||
public class BootJar extends Jar implements BootArchive {
|
||||
|
||||
private BootArchiveSupport support = new BootArchiveSupport("BOOT-INF/lib");
|
||||
private BootArchiveSupport support = new BootArchiveSupport(
|
||||
"org.springframework.boot.loader.JarLauncher", "BOOT-INF/lib");
|
||||
|
||||
private FileCollection classpath;
|
||||
|
||||
private String mainClass;
|
||||
|
||||
public BootJar() {
|
||||
this.support.setLoaderMainClass("org.springframework.boot.loader.JarLauncher");
|
||||
CopySpec bootInf = getRootSpec().addChildBeforeSpec(getMainSpec())
|
||||
.into("BOOT-INF");
|
||||
bootInf.into("lib", classpathFiles(File::isFile));
|
||||
|
||||
@@ -36,7 +36,8 @@ import org.gradle.api.tasks.bundling.War;
|
||||
*/
|
||||
public class BootWar extends War implements BootArchive {
|
||||
|
||||
private final BootArchiveSupport support = new BootArchiveSupport("WEB-INF/lib/",
|
||||
private final BootArchiveSupport support = new BootArchiveSupport(
|
||||
"org.springframework.boot.loader.WarLauncher", "WEB-INF/lib/",
|
||||
"WEB-INF/lib-provided");
|
||||
|
||||
private String mainClass;
|
||||
@@ -44,7 +45,6 @@ public class BootWar extends War implements BootArchive {
|
||||
private FileCollection providedClasspath;
|
||||
|
||||
public BootWar() {
|
||||
this.support.setLoaderMainClass("org.springframework.boot.loader.WarLauncher");
|
||||
getWebInf().into("lib-provided", (copySpec) -> {
|
||||
copySpec.from((Callable<Iterable<File>>) () -> {
|
||||
return this.providedClasspath == null ? Collections.emptyList()
|
||||
|
||||
@@ -53,6 +53,8 @@ class BootZipCopyAction implements CopyAction {
|
||||
|
||||
private final boolean preserveFileTimestamps;
|
||||
|
||||
private final boolean includeDefaultLoader;
|
||||
|
||||
private final Spec<FileTreeElement> requiresUnpack;
|
||||
|
||||
private final Spec<FileTreeElement> exclusions;
|
||||
@@ -62,10 +64,12 @@ class BootZipCopyAction implements CopyAction {
|
||||
private final Set<String> storedPathPrefixes;
|
||||
|
||||
BootZipCopyAction(File output, boolean preserveFileTimestamps,
|
||||
Spec<FileTreeElement> requiresUnpack, Spec<FileTreeElement> exclusions,
|
||||
LaunchScriptConfiguration launchScript, Set<String> storedPathPrefixes) {
|
||||
boolean includeDefaultLoader, Spec<FileTreeElement> requiresUnpack,
|
||||
Spec<FileTreeElement> exclusions, LaunchScriptConfiguration launchScript,
|
||||
Set<String> storedPathPrefixes) {
|
||||
this.output = output;
|
||||
this.preserveFileTimestamps = preserveFileTimestamps;
|
||||
this.includeDefaultLoader = includeDefaultLoader;
|
||||
this.requiresUnpack = requiresUnpack;
|
||||
this.exclusions = exclusions;
|
||||
this.launchScript = launchScript;
|
||||
@@ -79,7 +83,7 @@ class BootZipCopyAction implements CopyAction {
|
||||
FileOutputStream fileStream = new FileOutputStream(this.output);
|
||||
writeLaunchScriptIfNecessary(fileStream);
|
||||
zipStream = new ZipOutputStream(fileStream);
|
||||
writeLoaderClasses(zipStream);
|
||||
writeLoaderClassesIfNecessary(zipStream);
|
||||
}
|
||||
catch (IOException ex) {
|
||||
throw new GradleException("Failed to create " + this.output, ex);
|
||||
@@ -102,8 +106,13 @@ class BootZipCopyAction implements CopyAction {
|
||||
};
|
||||
}
|
||||
|
||||
private void writeLoaderClasses(ZipOutputStream out) {
|
||||
private void writeLoaderClassesIfNecessary(ZipOutputStream out) {
|
||||
if (this.includeDefaultLoader) {
|
||||
writeLoaderClasses(out);
|
||||
}
|
||||
}
|
||||
|
||||
private void writeLoaderClasses(ZipOutputStream out) {
|
||||
ZipEntry entry;
|
||||
try (ZipInputStream in = new ZipInputStream(getClass()
|
||||
.getResourceAsStream("/META-INF/loader/spring-boot-loader.jar"))) {
|
||||
|
||||
@@ -135,6 +135,20 @@ public abstract class AbstractBootArchiveTests<T extends Jar & BootArchive> {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void loaderIsWrittenToTheRootOfTheJarWhenUsingThePropertiesLauncher()
|
||||
throws IOException {
|
||||
this.task.setMainClass("com.example.Main");
|
||||
this.task.execute();
|
||||
this.task.getManifest().getAttributes().put("Main-Class",
|
||||
"org.springframework.boot.loader.PropertiesLauncher");
|
||||
try (JarFile jarFile = new JarFile(this.task.getArchivePath())) {
|
||||
assertThat(jarFile.getEntry(
|
||||
"org/springframework/boot/loader/LaunchedURLClassLoader.class"))
|
||||
.isNotNull();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void unpackCommentIsAddedToEntryIdentifiedByAPattern() throws IOException {
|
||||
this.task.setMainClass("com.example.Main");
|
||||
@@ -207,6 +221,9 @@ public abstract class AbstractBootArchiveTests<T extends Jar & BootArchive> {
|
||||
.isEqualTo("com.example.CustomLauncher");
|
||||
assertThat(jarFile.getManifest().getMainAttributes().getValue("Start-Class"))
|
||||
.isEqualTo("com.example.Main");
|
||||
assertThat(jarFile.getEntry(
|
||||
"org/springframework/boot/loader/LaunchedURLClassLoader.class"))
|
||||
.isNull();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user