Commit 5bf8f778 authored by Andy Wilkinson's avatar Andy Wilkinson

Don't write the default loader classes when a custom launcher is used

parent 2b44ad98
......@@ -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();
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment