Fix Gradle plugin task dependencies broken by removal of app plugin

8673250 updated the plugin so that the application plugin is no longer
applied by default. This exposed three problems:

 1. bootRepackage may run before findMainClass has run, leaving it with
    an unknown main class.
 2. findMainClass may run before the classes have been built, making it
    unable to find the main class by examining the class files
 3. The project's mainClassName property was still being used as a
    convention for the bootRun task's main property. If the application
    plugin has not be applied, then this property does not exist.

The first problem has been addressed by configuring bootRepackage to
depend on findMainClass.

The second problem has been addressed by configuring the main source
set's output as an input of findMainClass, and configuring findMainClass
to depend on the tasks that build the output.

The third problem has been addressed by only using the mainClassName
property if it exists and its value is not null. We then fallback to
using the mainClassName property on the project's extra properties in
the same way. 

See gh-2679
pull/3551/merge
Andy Wilkinson 9 years ago
parent 8673250955
commit 434f528e0a

@ -43,8 +43,7 @@ public class InstallTests {
// "install" from the application plugin was renamed "installApp" in Gradle
// 1.0
this.project.newBuild().forTasks("installApp")
.withArguments("-PbootVersion=" + BOOT_VERSION, "--stacktrace", "--info")
.run();
.withArguments("-PbootVersion=" + BOOT_VERSION, "--stacktrace").run();
}
}

@ -23,7 +23,7 @@ import org.junit.BeforeClass;
import org.junit.Test;
/**
* Tests for using the Gradle plugin's support for installing artifacts
* Tests for configuring a project's main class
*
* @author Dave Syer
*/
@ -35,11 +35,11 @@ public class MainClassTests {
@BeforeClass
public static void createProject() throws IOException {
project = new ProjectCreator().createProject("main-in-run");
project = new ProjectCreator().createProject("main-in-boot-run");
}
@Test
public void buildFromRunTask() {
public void mainFromBootRun() {
project.newBuild().forTasks("build")
.withArguments("-PbootVersion=" + BOOT_VERSION, "--info").run();
}

@ -12,7 +12,7 @@ apply plugin: 'spring-boot'
group = 'flatdir'
version = '0.0.0'
run {
bootRun {
main = 'Foo'
}

@ -10,11 +10,12 @@ buildscript {
apply plugin: 'java'
apply plugin: 'maven'
apply plugin: 'spring-boot'
apply plugin: 'application'
group = 'installer'
version = '0.0.0'
run {
bootRun {
main = 'org.springframework.boot.SpringApplication'
}

@ -14,7 +14,7 @@ apply plugin: 'spring-boot'
group = 'installer'
version = '0.0.0'
run {
bootRun {
main = 'org.springframework.boot.SpringApplication'
}

@ -31,6 +31,7 @@ import org.gradle.api.tasks.TaskDependency;
import org.gradle.api.tasks.bundling.Jar;
import org.springframework.boot.gradle.PluginFeatures;
import org.springframework.boot.gradle.SpringBootPluginExtension;
import org.springframework.boot.gradle.run.FindMainClassTask;
import org.springframework.boot.loader.tools.Library;
import org.springframework.boot.loader.tools.LibraryCallback;
import org.springframework.util.StringUtils;
@ -69,6 +70,7 @@ public class RepackagePluginFeatures implements PluginFeatures {
runtimeProjectDependencyJarTasks);
registerOutput(project, task);
ensureTaskRunsOnAssembly(project, task);
ensureMainClassHasBeenFound(project, task);
}
private void registerOutput(Project project, final RepackageTask task) {
@ -89,6 +91,10 @@ public class RepackagePluginFeatures implements PluginFeatures {
project.getTasks().getByName(BasePlugin.ASSEMBLE_TASK_NAME).dependsOn(task);
}
private void ensureMainClassHasBeenFound(Project project, Task task) {
task.dependsOn(project.getTasks().withType(FindMainClassTask.class));
}
/**
* Register BootRepackage so that we can use task {@code foo(type: BootRepackage)}.
*/

@ -25,6 +25,8 @@ import java.util.concurrent.TimeUnit;
import org.gradle.api.Action;
import org.gradle.api.DefaultTask;
import org.gradle.api.Project;
import org.gradle.api.Task;
import org.gradle.api.plugins.ExtraPropertiesExtension;
import org.gradle.api.tasks.TaskAction;
import org.gradle.api.tasks.bundling.Jar;
import org.springframework.boot.gradle.SpringBootPluginExtension;
@ -194,16 +196,27 @@ public class RepackageTask extends DefaultTask {
}
private void setMainClass(Repackager repackager) {
String mainClass = (String) getProject().property("mainClassName");
String mainClass;
if (getProject().hasProperty("mainClassName")) {
mainClass = (String) getProject().property("mainClassName");
}
else {
ExtraPropertiesExtension extraProperties = (ExtraPropertiesExtension) getProject()
.getExtensions().getByName("ext");
mainClass = (String) extraProperties.get("mainClassName");
}
if (RepackageTask.this.mainClass != null) {
mainClass = RepackageTask.this.mainClass;
}
else if (this.extension.getMainClass() != null) {
mainClass = this.extension.getMainClass();
}
else if (getProject().getTasks().getByName("run").hasProperty("main")) {
mainClass = (String) getProject().getTasks().getByName("run")
.property("main");
else {
Task runTask = getProject().getTasks().findByName("run");
if (runTask != null && runTask.hasProperty("main")) {
mainClass = (String) getProject().getTasks().getByName("run")
.property("main");
}
}
getLogger().info("Setting mainClass: " + mainClass);
repackager.setMainClass(mainClass);
@ -211,7 +224,7 @@ public class RepackageTask extends DefaultTask {
private LaunchScript getLaunchScript() throws IOException {
if (this.extension.isExecutable()
|| extension.getEmbeddedLaunchScript() != null) {
|| this.extension.getEmbeddedLaunchScript() != null) {
return new DefaultLaunchScript(this.extension.getEmbeddedLaunchScript(),
this.extension.getEmbeddedLaunchScriptProperties());
}

@ -23,7 +23,8 @@ 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.SourceSet;
import org.gradle.api.tasks.Input;
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;
@ -38,6 +39,14 @@ import org.springframework.boot.loader.tools.MainClassFinder;
*/
public class FindMainClassTask extends DefaultTask {
@Input
private SourceSetOutput mainClassSourceSetOutput;
public void setMainClassSourceSetOutput(SourceSetOutput sourceSetOutput) {
this.mainClassSourceSetOutput = sourceSetOutput;
this.dependsOn(this.mainClassSourceSetOutput.getBuildDependencies());
}
@TaskAction
public void setMainClassNameProperty() {
Project project = getProject();
@ -80,16 +89,23 @@ public class FindMainClassTask extends DefaultTask {
mainClass = (String) runTask.property("main");
}
if (mainClass == null) {
Task bootRunTask = project.getTasks().findByName("bootRun");
if (bootRunTask != null) {
mainClass = (String) bootRunTask.property("main");
}
}
if (mainClass == null) {
// Search
SourceSet mainSourceSet = SourceSets.findMainSourceSet(project);
if (mainSourceSet != null) {
if (this.mainClassSourceSetOutput != null) {
project.getLogger().debug(
"Looking for main in: "
+ mainSourceSet.getOutput().getClassesDir());
+ this.mainClassSourceSetOutput.getClassesDir());
try {
mainClass = MainClassFinder.findSingleMainClass(mainSourceSet
.getOutput().getClassesDir());
mainClass = MainClassFinder
.findSingleMainClass(this.mainClassSourceSetOutput
.getClassesDir());
project.getLogger().info("Computed main class: " + mainClass);
}
catch (IOException ex) {

@ -22,8 +22,10 @@ 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.JavaPluginConvention;
import org.gradle.api.tasks.JavaExec;
import org.gradle.api.tasks.SourceSet;
import org.gradle.api.tasks.application.CreateStartScripts;
import org.springframework.boot.gradle.PluginFeatures;
@ -45,7 +47,12 @@ public class RunPluginFeatures implements PluginFeatures {
}
private void mainClassNameFinder(Project project) {
project.getTasks().create(FIND_MAIN_CLASS_TASK_NAME, FindMainClassTask.class);
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) {
@ -69,7 +76,17 @@ public class RunPluginFeatures implements PluginFeatures {
run.getConventionMapping().map("main", new Callable<Object>() {
@Override
public Object call() throws Exception {
return project.property("mainClassName");
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>() {

Loading…
Cancel
Save