From 1043239de09218cc77f1659ba435649dfca6c4d7 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Tue, 29 Mar 2016 11:03:47 +0100 Subject: [PATCH] Ignore non-JavaExec run task when finding application's main class Previously, FindMainClassTask would look for a property named main on any class named run. This was based on the assumption that the run task would be a JavaExec task (typically provided by the application plugin). If the run task was not a JavaExec task (more accurately, if it did not have a main property) this would result in a build failure due to trying to read a non-existent property. This commit updates FindMainClassTask to only use the main property of the run task if the task is a JavaExec task. This guarantees that the property will exist on the task, and unlike using any property named main on a task named run, also guarantee that its value will refer to a Java class with a main method. Closes gh-5501 --- .../boot/gradle/MainClassTests.java | 37 ++++++++++++++++--- ...n-in-boot-run.gradle => main-class.gradle} | 11 +++++- .../boot/gradle/run/FindMainClassTask.java | 17 +++++++-- 3 files changed, 54 insertions(+), 11 deletions(-) rename spring-boot-integration-tests/spring-boot-gradle-tests/src/test/resources/{main-in-boot-run.gradle => main-class.gradle} (70%) diff --git a/spring-boot-integration-tests/spring-boot-gradle-tests/src/test/java/org/springframework/boot/gradle/MainClassTests.java b/spring-boot-integration-tests/spring-boot-gradle-tests/src/test/java/org/springframework/boot/gradle/MainClassTests.java index 7712e91fdc..ac712ea879 100644 --- a/spring-boot-integration-tests/spring-boot-gradle-tests/src/test/java/org/springframework/boot/gradle/MainClassTests.java +++ b/spring-boot-integration-tests/spring-boot-gradle-tests/src/test/java/org/springframework/boot/gradle/MainClassTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2015 the original author or authors. + * 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. @@ -18,30 +18,57 @@ package org.springframework.boot.gradle; import java.io.IOException; +import org.gradle.tooling.BuildException; import org.gradle.tooling.ProjectConnection; import org.junit.BeforeClass; import org.junit.Test; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertThat; + /** * Tests for configuring a project's main class * * @author Dave Syer + * @author Andy Wilkinson */ public class MainClassTests { - private static ProjectConnection project; - private static final String BOOT_VERSION = Versions.getBootVersion(); + private static ProjectConnection project; + @BeforeClass public static void createProject() throws IOException { - project = new ProjectCreator().createProject("main-in-boot-run"); + project = new ProjectCreator().createProject("main-class"); } @Test public void mainFromBootRun() { project.newBuild().forTasks("build") - .withArguments("-PbootVersion=" + BOOT_VERSION, "--info").run(); + .withArguments("-PbootVersion=" + BOOT_VERSION, "-PbootRunMain=true") + .run(); + } + + @Test + public void nonJavaExecRunTaskIsIgnored() { + try { + project.newBuild().forTasks("build").withArguments( + "-PbootVersion=" + BOOT_VERSION, "-PnonJavaExecRun=true").run(); + } + catch (BuildException ex) { + Throwable rootCause = getRootCause(ex); + assertThat(rootCause.getMessage(), is(equalTo("Unable to find main class"))); + } + } + + private Throwable getRootCause(Throwable ex) { + Throwable candidate = ex; + while (candidate.getCause() != null) { + candidate = candidate.getCause(); + } + return candidate; } } diff --git a/spring-boot-integration-tests/spring-boot-gradle-tests/src/test/resources/main-in-boot-run.gradle b/spring-boot-integration-tests/spring-boot-gradle-tests/src/test/resources/main-class.gradle similarity index 70% rename from spring-boot-integration-tests/spring-boot-gradle-tests/src/test/resources/main-in-boot-run.gradle rename to spring-boot-integration-tests/spring-boot-gradle-tests/src/test/resources/main-class.gradle index ad06027a0f..982cd946d1 100644 --- a/spring-boot-integration-tests/spring-boot-gradle-tests/src/test/resources/main-in-boot-run.gradle +++ b/spring-boot-integration-tests/spring-boot-gradle-tests/src/test/resources/main-class.gradle @@ -14,10 +14,17 @@ apply plugin: 'spring-boot' group = 'installer' version = '0.0.0' -bootRun { - main = 'org.springframework.boot.SpringApplication' +if (project.hasProperty('bootRunMain')) { + bootRun { + main = 'org.springframework.boot.SpringApplication' + } +} + +if (project.hasProperty('nonJavaExecRun')) { + task run { } } + jar { baseName = 'installer' } diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/run/FindMainClassTask.java b/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/run/FindMainClassTask.java index a433f812e5..b4c052b51b 100644 --- a/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/run/FindMainClassTask.java +++ b/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/run/FindMainClassTask.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2015 the original author or authors. + * 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. @@ -24,6 +24,7 @@ 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; @@ -85,9 +86,9 @@ public class FindMainClassTask extends DefaultTask { mainClass = application.getMainClassName(); } - Task runTask = project.getTasks().findByName("run"); + JavaExec runTask = findRunTask(project); if (mainClass == null && runTask != null) { - mainClass = (String) runTask.property("main"); + mainClass = runTask.getMain(); } if (mainClass == null) { @@ -122,9 +123,17 @@ public class FindMainClassTask extends DefaultTask { application.setMainClassName(mainClass); } if (runTask != null && !runTask.hasProperty("main")) { - runTask.setProperty("main", mainClass); + 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; + } }