Simplify bootRun main class configuration by reusing MainClassSupplier
This commit is contained in:
parent
f16efb2277
commit
b4e2044b9e
|
|
@ -14,10 +14,11 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.gradle.bundling;
|
||||
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;
|
||||
|
|
@ -31,41 +32,60 @@ import org.springframework.boot.loader.tools.MainClassFinder;
|
|||
*
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
class MainClassSupplier implements Supplier<String> {
|
||||
public class MainClassSupplier implements Supplier<String> {
|
||||
|
||||
private static final String SPRING_BOOT_APPLICATION_CLASS_NAME = "org.springframework.boot.autoconfigure.SpringBootApplication";
|
||||
|
||||
private final Supplier<FileCollection> classpathSupplier;
|
||||
|
||||
private String mainClass;
|
||||
|
||||
MainClassSupplier(Supplier<FileCollection> classpathSupplier) {
|
||||
/**
|
||||
* Creates a new {@code MainClassSupplier} that will fall back to searching
|
||||
* directories in the classpath supplied by the given {@code classpathSupplier} for
|
||||
* the application's main class.
|
||||
*
|
||||
* @param classpathSupplier the supplier of the classpath
|
||||
*/
|
||||
public MainClassSupplier(Supplier<FileCollection> classpathSupplier) {
|
||||
this.classpathSupplier = classpathSupplier;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String get() {
|
||||
if (this.mainClass != null) {
|
||||
return this.mainClass;
|
||||
if (this.mainClass == null) {
|
||||
this.mainClass = findMainClass();
|
||||
}
|
||||
return findMainClass();
|
||||
return this.mainClass;
|
||||
}
|
||||
|
||||
private String findMainClass() {
|
||||
FileCollection classpath = this.classpathSupplier.get();
|
||||
return classpath == null ? null
|
||||
: classpath.filter(File::isDirectory).getFiles().stream()
|
||||
.map(this::findMainClass).findFirst().orElse(null);
|
||||
if (classpath == null) {
|
||||
return null;
|
||||
}
|
||||
return classpath.filter(File::isDirectory).getFiles().stream()
|
||||
.map(this::findMainClass).filter(Objects::nonNull).findFirst()
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
private String findMainClass(File file) {
|
||||
try {
|
||||
return MainClassFinder.findSingleMainClass(file);
|
||||
String result = MainClassFinder.findSingleMainClass(file,
|
||||
SPRING_BOOT_APPLICATION_CLASS_NAME);
|
||||
return result;
|
||||
}
|
||||
catch (IOException ex) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
void setMainClass(String mainClass) {
|
||||
/**
|
||||
* Sets the {@code mainClass} that will be supplied.
|
||||
*
|
||||
* @param mainClass the main class to supply
|
||||
*/
|
||||
public void setMainClass(String mainClass) {
|
||||
this.mainClass = mainClass;
|
||||
}
|
||||
|
||||
|
|
@ -28,6 +28,8 @@ 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.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -29,6 +29,8 @@ 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.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ 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;
|
||||
|
||||
/**
|
||||
|
|
@ -33,9 +34,13 @@ import org.springframework.boot.loader.tools.FileUtils;
|
|||
*
|
||||
* @author Dave Syer
|
||||
* @author Phillip Webb
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
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
|
||||
|
|
@ -62,6 +67,17 @@ 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());
|
||||
|
|
|
|||
|
|
@ -1,143 +0,0 @@
|
|||
/*
|
||||
* Copyright 2012-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.gradle.run;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.gradle.api.DefaultTask;
|
||||
import org.gradle.api.Project;
|
||||
import org.gradle.api.Task;
|
||||
import org.gradle.api.plugins.ApplicationPluginConvention;
|
||||
import org.gradle.api.plugins.ExtraPropertiesExtension;
|
||||
import org.gradle.api.tasks.Input;
|
||||
import org.gradle.api.tasks.JavaExec;
|
||||
import org.gradle.api.tasks.SourceSetOutput;
|
||||
import org.gradle.api.tasks.TaskAction;
|
||||
|
||||
import org.springframework.boot.gradle.SpringBootPluginExtension;
|
||||
import org.springframework.boot.loader.tools.MainClassFinder;
|
||||
|
||||
/**
|
||||
* Task to find and set the 'mainClassName' convention when it's missing by searching the
|
||||
* main source code.
|
||||
*
|
||||
* @author Dave Syer
|
||||
* @author Phillip Webb
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
public class FindMainClassTask extends DefaultTask {
|
||||
|
||||
private static final String SPRING_BOOT_APPLICATION_CLASS_NAME = "org.springframework.boot.autoconfigure.SpringBootApplication";
|
||||
|
||||
@Input
|
||||
private SourceSetOutput mainClassSourceSetOutput;
|
||||
|
||||
public void setMainClassSourceSetOutput(SourceSetOutput sourceSetOutput) {
|
||||
this.mainClassSourceSetOutput = sourceSetOutput;
|
||||
this.dependsOn(this.mainClassSourceSetOutput.getBuildDependencies());
|
||||
}
|
||||
|
||||
@TaskAction
|
||||
public void setMainClassNameProperty() {
|
||||
Project project = getProject();
|
||||
if (!project.hasProperty("mainClassName")
|
||||
|| project.property("mainClassName") == null) {
|
||||
String mainClass = findMainClass();
|
||||
if (project.hasProperty("mainClassName")) {
|
||||
project.setProperty("mainClassName", mainClass);
|
||||
}
|
||||
else {
|
||||
ExtraPropertiesExtension extraProperties = (ExtraPropertiesExtension) project
|
||||
.getExtensions().getByName("ext");
|
||||
extraProperties.set("mainClassName", mainClass);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String findMainClass() {
|
||||
Project project = getProject();
|
||||
|
||||
String mainClass = null;
|
||||
|
||||
// Try the SpringBoot extension setting
|
||||
SpringBootPluginExtension bootExtension = project.getExtensions()
|
||||
.getByType(SpringBootPluginExtension.class);
|
||||
if (bootExtension.getMainClass() != null) {
|
||||
mainClass = bootExtension.getMainClass();
|
||||
}
|
||||
|
||||
ApplicationPluginConvention application = (ApplicationPluginConvention) project
|
||||
.getConvention().getPlugins().get("application");
|
||||
|
||||
if (mainClass == null && application != null) {
|
||||
// Try the Application extension setting
|
||||
mainClass = application.getMainClassName();
|
||||
}
|
||||
|
||||
JavaExec runTask = findRunTask(project);
|
||||
if (mainClass == null && runTask != null) {
|
||||
mainClass = runTask.getMain();
|
||||
}
|
||||
|
||||
if (mainClass == null) {
|
||||
Task bootRunTask = project.getTasks().findByName("bootRun");
|
||||
if (bootRunTask != null) {
|
||||
mainClass = (String) bootRunTask.property("main");
|
||||
}
|
||||
}
|
||||
|
||||
if (mainClass == null) {
|
||||
// Search
|
||||
if (this.mainClassSourceSetOutput != null) {
|
||||
project.getLogger().debug("Looking for main in: "
|
||||
+ this.mainClassSourceSetOutput.getClassesDir());
|
||||
try {
|
||||
mainClass = MainClassFinder.findSingleMainClass(
|
||||
this.mainClassSourceSetOutput.getClassesDir(),
|
||||
SPRING_BOOT_APPLICATION_CLASS_NAME);
|
||||
project.getLogger().info("Computed main class: " + mainClass);
|
||||
}
|
||||
catch (IOException ex) {
|
||||
throw new IllegalStateException("Cannot find main class", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
project.getLogger().info("Found main: " + mainClass);
|
||||
|
||||
if (bootExtension.getMainClass() == null) {
|
||||
bootExtension.setMainClass(mainClass);
|
||||
}
|
||||
if (application != null && application.getMainClassName() == null) {
|
||||
application.setMainClassName(mainClass);
|
||||
}
|
||||
if (runTask != null && !runTask.hasProperty("main")) {
|
||||
runTask.setMain(mainClass);
|
||||
}
|
||||
|
||||
return mainClass;
|
||||
}
|
||||
|
||||
private JavaExec findRunTask(Project project) {
|
||||
Task runTask = project.getTasks().findByName("run");
|
||||
if (runTask instanceof JavaExec) {
|
||||
return (JavaExec) runTask;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -19,14 +19,9 @@ package org.springframework.boot.gradle.run;
|
|||
import java.util.Collections;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
import org.gradle.api.Action;
|
||||
import org.gradle.api.Project;
|
||||
import org.gradle.api.Task;
|
||||
import org.gradle.api.plugins.ExtraPropertiesExtension;
|
||||
import org.gradle.api.plugins.JavaPlugin;
|
||||
import org.gradle.api.plugins.JavaPluginConvention;
|
||||
import org.gradle.api.tasks.SourceSet;
|
||||
import org.gradle.api.tasks.application.CreateStartScripts;
|
||||
|
||||
import org.springframework.boot.gradle.PluginFeatures;
|
||||
|
||||
|
|
@ -37,35 +32,15 @@ import org.springframework.boot.gradle.PluginFeatures;
|
|||
*/
|
||||
public class RunPluginFeatures implements PluginFeatures {
|
||||
|
||||
private static final String FIND_MAIN_CLASS_TASK_NAME = "findMainClass";
|
||||
|
||||
private static final String RUN_APP_TASK_NAME = "bootRun";
|
||||
|
||||
@Override
|
||||
public void apply(Project project) {
|
||||
project.getPlugins().withType(JavaPlugin.class, (javaPlugin) -> {
|
||||
mainClassNameFinder(project);
|
||||
addBootRunTask(project);
|
||||
});
|
||||
}
|
||||
|
||||
private void mainClassNameFinder(Project project) {
|
||||
FindMainClassTask findMainClassTask = project.getTasks()
|
||||
.create(FIND_MAIN_CLASS_TASK_NAME, FindMainClassTask.class);
|
||||
SourceSet mainSourceSet = SourceSets.findMainSourceSet(project);
|
||||
if (mainSourceSet != null) {
|
||||
findMainClassTask.setMainClassSourceSetOutput(mainSourceSet.getOutput());
|
||||
}
|
||||
project.getTasks().all(new Action<Task>() {
|
||||
@Override
|
||||
public void execute(Task task) {
|
||||
if (task instanceof BootRunTask || task instanceof CreateStartScripts) {
|
||||
task.dependsOn(FIND_MAIN_CLASS_TASK_NAME);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void addBootRunTask(final Project project) {
|
||||
final JavaPluginConvention javaConvention = project.getConvention()
|
||||
.getPlugin(JavaPluginConvention.class);
|
||||
|
|
@ -76,22 +51,6 @@ public class RunPluginFeatures implements PluginFeatures {
|
|||
run.setGroup("application");
|
||||
run.setClasspath(
|
||||
javaConvention.getSourceSets().findByName("main").getRuntimeClasspath());
|
||||
run.getConventionMapping().map("main", new Callable<Object>() {
|
||||
@Override
|
||||
public Object call() throws Exception {
|
||||
if (project.hasProperty("mainClassName")
|
||||
&& project.property("mainClassName") != null) {
|
||||
return project.property("mainClassName");
|
||||
}
|
||||
ExtraPropertiesExtension extraPropertiesExtension = (ExtraPropertiesExtension) project
|
||||
.getExtensions().getByName("ext");
|
||||
if (extraPropertiesExtension.has("mainClassName")
|
||||
&& extraPropertiesExtension.get("mainClassName") != null) {
|
||||
return extraPropertiesExtension.get("mainClassName");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
});
|
||||
run.getConventionMapping().map("jvmArgs", new Callable<Object>() {
|
||||
@Override
|
||||
public Object call() throws Exception {
|
||||
|
|
|
|||
Loading…
Reference in New Issue