diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/MainClassSupplier.java b/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/MainClassResolver.java similarity index 53% rename from spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/MainClassSupplier.java rename to spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/MainClassResolver.java index 0b493f1a67..aa85cbf10a 100644 --- a/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/MainClassSupplier.java +++ b/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/MainClassResolver.java @@ -19,52 +19,40 @@ package org.springframework.boot.gradle; import java.io.File; import java.io.IOException; import java.util.Objects; -import java.util.function.Supplier; import org.gradle.api.file.FileCollection; import org.springframework.boot.loader.tools.MainClassFinder; /** - * Supplies the main class for an application by returning a configured main class if - * available. If a main class is not available, directories in the application's classpath - * are searched. + * Resolves the main class for an application. * * @author Andy Wilkinson */ -public class MainClassSupplier implements Supplier { +public class MainClassResolver { private static final String SPRING_BOOT_APPLICATION_CLASS_NAME = "org.springframework.boot.autoconfigure.SpringBootApplication"; - private final Supplier classpathSupplier; - - private String mainClass; + private final FileCollection classpath; /** - * Creates a new {@code MainClassSupplier} that will fall back to searching - * directories in the classpath supplied by the given {@code classpathSupplier} for + * Creates a new {@code MainClassResolver} that will search + * directories in the given {@code classpath} for * the application's main class. * - * @param classpathSupplier the supplier of the classpath + * @param classpath the classpath */ - public MainClassSupplier(Supplier classpathSupplier) { - this.classpathSupplier = classpathSupplier; + public MainClassResolver(FileCollection classpath) { + this.classpath = classpath; } - @Override - public String get() { - if (this.mainClass == null) { - this.mainClass = findMainClass(); - } - return this.mainClass; - } - - private String findMainClass() { - FileCollection classpath = this.classpathSupplier.get(); - if (classpath == null) { - return null; - } - return classpath.filter(File::isDirectory).getFiles().stream() + /** + * Resolves the main class. + * + * @return the main class or {@code null} + */ + public String resolveMainClass() { + return this.classpath.filter(File::isDirectory).getFiles().stream() .map(this::findMainClass).filter(Objects::nonNull).findFirst() .orElse(null); } @@ -80,13 +68,4 @@ public class MainClassSupplier implements Supplier { } } - /** - * Sets the {@code mainClass} that will be supplied. - * - * @param mainClass the main class to supply - */ - public void setMainClass(String mainClass) { - this.mainClass = mainClass; - } - } diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/bundling/BootArchiveSupport.java b/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/bundling/BootArchiveSupport.java index 2dbc1040a9..7f24622081 100644 --- a/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/bundling/BootArchiveSupport.java +++ b/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/bundling/BootArchiveSupport.java @@ -37,25 +37,21 @@ class BootArchiveSupport { private final PatternSet requiresUnpack = new PatternSet(); - private final MainClassSupplier mainClassSupplier; - private final Set storedPathPrefixes; private String loaderMainClass; private LaunchScriptConfiguration launchScript = new LaunchScriptConfiguration(); - BootArchiveSupport(MainClassSupplier mainClassSupplier, - String... storedPathPrefixes) { - this.mainClassSupplier = mainClassSupplier; + BootArchiveSupport(String... storedPathPrefixes) { this.storedPathPrefixes = new HashSet<>(Arrays.asList(storedPathPrefixes)); this.requiresUnpack.include(Specs.satisfyNone()); } - void configureManifest(Jar jar) { + void configureManifest(Jar jar, String mainClass) { Attributes attributes = jar.getManifest().getAttributes(); attributes.putIfAbsent("Main-Class", this.loaderMainClass); - attributes.putIfAbsent("Start-Class", this.mainClassSupplier.get()); + attributes.putIfAbsent("Start-Class", mainClass); } CopyAction createCopyAction(Jar jar) { diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/bundling/BootJar.java b/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/bundling/BootJar.java index 03aaeaaaeb..7625ff3cf6 100644 --- a/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/bundling/BootJar.java +++ b/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/bundling/BootJar.java @@ -28,8 +28,6 @@ import org.gradle.api.internal.file.copy.CopyAction; import org.gradle.api.specs.Spec; import org.gradle.api.tasks.bundling.Jar; -import org.springframework.boot.gradle.MainClassSupplier; - /** * A custom {@link Jar} task that produces a Spring Boot executable jar. * @@ -37,10 +35,7 @@ import org.springframework.boot.gradle.MainClassSupplier; */ public class BootJar extends Jar implements BootArchive { - private final MainClassSupplier mainClassSupplier = new MainClassSupplier( - this::getClasspath); - - private BootArchiveSupport support = new BootArchiveSupport(this.mainClassSupplier, "BOOT-INF/lib"); + private BootArchiveSupport support = new BootArchiveSupport("BOOT-INF/lib"); private FileCollection classpath; @@ -65,7 +60,7 @@ public class BootJar extends Jar implements BootArchive { @Override public void copy() { - this.support.configureManifest(this); + this.support.configureManifest(this, getMainClass()); super.copy(); } @@ -82,7 +77,6 @@ public class BootJar extends Jar implements BootArchive { @Override public void setMainClass(String mainClass) { this.mainClass = mainClass; - this.mainClassSupplier.setMainClass(mainClass); } @Override diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/bundling/BootWar.java b/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/bundling/BootWar.java index 33f425ed19..647f42ebf0 100644 --- a/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/bundling/BootWar.java +++ b/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/bundling/BootWar.java @@ -29,8 +29,6 @@ import org.gradle.api.specs.Spec; import org.gradle.api.tasks.Optional; import org.gradle.api.tasks.bundling.War; -import org.springframework.boot.gradle.MainClassSupplier; - /** * A custom {@link War} task that produces a Spring Boot executable war. * @@ -38,11 +36,8 @@ import org.springframework.boot.gradle.MainClassSupplier; */ public class BootWar extends War implements BootArchive { - private final MainClassSupplier mainClassSupplier = new MainClassSupplier( - this::getClasspath); - - private final BootArchiveSupport support = new BootArchiveSupport( - this.mainClassSupplier, "WEB-INF/lib/", "WEB-INF/lib-provided"); + private final BootArchiveSupport support = new BootArchiveSupport("WEB-INF/lib/", + "WEB-INF/lib-provided"); private String mainClass; @@ -60,7 +55,7 @@ public class BootWar extends War implements BootArchive { @Override public void copy() { - this.support.configureManifest(this); + this.support.configureManifest(this, getMainClass()); super.copy(); } @@ -77,7 +72,6 @@ public class BootWar extends War implements BootArchive { @Override public void setMainClass(String mainClass) { this.mainClass = mainClass; - this.mainClassSupplier.setMainClass(mainClass); } @Override diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/bundling/BundlingPluginFeatures.java b/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/bundling/BundlingPluginFeatures.java index 92135c6ff8..5baa4a9cbc 100644 --- a/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/bundling/BundlingPluginFeatures.java +++ b/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/bundling/BundlingPluginFeatures.java @@ -37,6 +37,7 @@ import org.gradle.api.plugins.WarPlugin; import org.gradle.api.tasks.SourceSet; import org.gradle.api.tasks.Upload; +import org.springframework.boot.gradle.MainClassResolver; import org.springframework.boot.gradle.PluginFeatures; /** @@ -65,6 +66,9 @@ public class BundlingPluginFeatures implements PluginFeatures { ArchivePublishArtifact artifact = new ArchivePublishArtifact(bootWar); this.singlePublishedArtifact.addCandidate(artifact); project.getComponents().add(new BootSoftwareComponent(artifact, "bootWeb")); + bootWar.conventionMapping("mainClass", () -> { + return new MainClassResolver(bootWar.getClasspath()).resolveMainClass(); + }); } private void configureBootJarTask(Project project) { @@ -79,6 +83,9 @@ public class BundlingPluginFeatures implements PluginFeatures { ArchivePublishArtifact artifact = new ArchivePublishArtifact(bootJar); this.singlePublishedArtifact.addCandidate(artifact); project.getComponents().add(new BootSoftwareComponent(artifact, "bootJava")); + bootJar.conventionMapping("mainClass", () -> { + return new MainClassResolver(bootJar.getClasspath()).resolveMainClass(); + }); } private void configureBootArchivesUpload(Project project) { diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/run/BootRunTask.java b/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/run/BootRunTask.java index 9f40aacdb9..c5808cd0d1 100644 --- a/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/run/BootRunTask.java +++ b/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/run/BootRunTask.java @@ -26,7 +26,6 @@ import org.gradle.api.internal.file.collections.SimpleFileCollection; import org.gradle.api.tasks.JavaExec; import org.gradle.api.tasks.SourceSet; -import org.springframework.boot.gradle.MainClassSupplier; import org.springframework.boot.loader.tools.FileUtils; /** @@ -38,9 +37,6 @@ import org.springframework.boot.loader.tools.FileUtils; */ public class BootRunTask extends JavaExec { - private final MainClassSupplier mainClassSupplier = new MainClassSupplier( - this::getClasspath); - /** * Whether or not resources (typically in {@code src/main/resources} are added * directly to the classpath. When enabled, this allows live in-place editing of @@ -67,17 +63,6 @@ public class BootRunTask extends JavaExec { super.exec(); } - @Override - public String getMain() { - return this.mainClassSupplier.get(); - } - - @Override - public JavaExec setMain(String mainClassName) { - this.mainClassSupplier.setMainClass(mainClassName); - return super.setMain(mainClassName); - } - private void addResourcesIfNecessary() { if (this.addResources) { SourceSet mainSourceSet = SourceSets.findMainSourceSet(getProject()); diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/run/RunPluginFeatures.java b/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/run/RunPluginFeatures.java index 41b335b83e..17e243334d 100644 --- a/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/run/RunPluginFeatures.java +++ b/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/run/RunPluginFeatures.java @@ -23,6 +23,7 @@ import org.gradle.api.Project; import org.gradle.api.plugins.JavaPlugin; import org.gradle.api.plugins.JavaPluginConvention; +import org.springframework.boot.gradle.MainClassResolver; import org.springframework.boot.gradle.PluginFeatures; /** @@ -60,6 +61,9 @@ public class RunPluginFeatures implements PluginFeatures { return Collections.emptyList(); } }); + run.conventionMapping("main", () -> { + return new MainClassResolver(run.getClasspath()).resolveMainClass(); + }); } }