Use application plugin properties by convention when it is applied

bootRun's main and jvmArgs properties use mainClassName and
applicationDefaultJvmArgs respectively by convention.

bootJar and bootWar's mainClass property uses mainClassName by
convention.
This commit is contained in:
Andy Wilkinson 2017-03-28 14:41:12 +01:00
parent 188c9e0f42
commit 1dc5c484f0
8 changed files with 108 additions and 17 deletions

View File

@ -19,6 +19,7 @@ package org.springframework.boot.gradle.bundling;
import java.util.Collections; import java.util.Collections;
import java.util.Set; import java.util.Set;
import java.util.concurrent.Callable; import java.util.concurrent.Callable;
import java.util.function.Supplier;
import org.gradle.api.Project; import org.gradle.api.Project;
import org.gradle.api.artifacts.Configuration; import org.gradle.api.artifacts.Configuration;
@ -66,9 +67,8 @@ public class BundlingPluginFeatures implements PluginFeatures {
ArchivePublishArtifact artifact = new ArchivePublishArtifact(bootWar); ArchivePublishArtifact artifact = new ArchivePublishArtifact(bootWar);
this.singlePublishedArtifact.addCandidate(artifact); this.singlePublishedArtifact.addCandidate(artifact);
project.getComponents().add(new BootSoftwareComponent(artifact, "bootWeb")); project.getComponents().add(new BootSoftwareComponent(artifact, "bootWeb"));
bootWar.conventionMapping("mainClass", () -> { bootWar.conventionMapping("mainClass",
return new MainClassResolver(bootWar.getClasspath()).resolveMainClass(); mainClassConvention(project, bootWar::getClasspath));
});
} }
private void configureBootJarTask(Project project) { private void configureBootJarTask(Project project) {
@ -83,9 +83,18 @@ public class BundlingPluginFeatures implements PluginFeatures {
ArchivePublishArtifact artifact = new ArchivePublishArtifact(bootJar); ArchivePublishArtifact artifact = new ArchivePublishArtifact(bootJar);
this.singlePublishedArtifact.addCandidate(artifact); this.singlePublishedArtifact.addCandidate(artifact);
project.getComponents().add(new BootSoftwareComponent(artifact, "bootJava")); project.getComponents().add(new BootSoftwareComponent(artifact, "bootJava"));
bootJar.conventionMapping("mainClass", () -> { bootJar.conventionMapping("mainClass",
return new MainClassResolver(bootJar.getClasspath()).resolveMainClass(); mainClassConvention(project, bootJar::getClasspath));
}); }
private Callable<Object> mainClassConvention(Project project,
Supplier<FileCollection> classpathSupplier) {
return () -> {
if (project.hasProperty("mainClassName")) {
return project.property("mainClassName");
}
return new MainClassResolver(classpathSupplier.get()).resolveMainClass();
};
} }
private void configureBootArchivesUpload(Project project) { private void configureBootArchivesUpload(Project project) {

View File

@ -44,26 +44,25 @@ public class RunPluginFeatures implements PluginFeatures {
}); });
} }
private void addBootRunTask(final Project project) { private void addBootRunTask(Project project) {
final JavaPluginConvention javaConvention = project.getConvention() JavaPluginConvention javaConvention = project.getConvention()
.getPlugin(JavaPluginConvention.class); .getPlugin(JavaPluginConvention.class);
BootRun run = project.getTasks().create(RUN_APP_TASK_NAME, BootRun.class); BootRun run = project.getTasks().create(RUN_APP_TASK_NAME, BootRun.class);
run.setDescription("Run the project with support for " run.setDescription("Run the project with support for "
+ "auto-detecting main class and reloading static resources"); + "auto-detecting main class and reloading static resources");
run.setGroup("application"); run.setGroup("application");
run.classpath(javaConvention.getSourceSets() run.classpath(javaConvention.getSourceSets()
.findByName(SourceSet.MAIN_SOURCE_SET_NAME).getRuntimeClasspath()); .findByName(SourceSet.MAIN_SOURCE_SET_NAME).getRuntimeClasspath());
run.getConventionMapping().map("jvmArgs", new Callable<Object>() { run.getConventionMapping().map("jvmArgs", ((Callable<Object>) () -> {
@Override if (project.hasProperty("applicationDefaultJvmArgs")) {
public Object call() throws Exception { return project.property("applicationDefaultJvmArgs");
if (project.hasProperty("applicationDefaultJvmArgs")) {
return project.property("applicationDefaultJvmArgs");
}
return Collections.emptyList();
} }
}); return Collections.emptyList();
}));
run.conventionMapping("main", () -> { run.conventionMapping("main", () -> {
if (project.hasProperty("mainClassName")) {
return project.property("mainClassName");
}
return new MainClassResolver(run.getClasspath()).resolveMainClass(); return new MainClassResolver(run.getClasspath()).resolveMainClass();
}); });
} }

View File

@ -16,7 +16,9 @@
package org.springframework.boot.gradle.bundling; package org.springframework.boot.gradle.bundling;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.jar.JarFile;
import org.gradle.testkit.runner.InvalidRunnerConfigurationException; import org.gradle.testkit.runner.InvalidRunnerConfigurationException;
import org.gradle.testkit.runner.TaskOutcome; import org.gradle.testkit.runner.TaskOutcome;
@ -97,4 +99,17 @@ public abstract class AbstractBootArchiveIntegrationTests {
.getOutcome()).isEqualTo(TaskOutcome.SUCCESS); .getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
} }
@Test
public void applicationPluginMainClassNameIsUsed() throws IOException {
assertThat(this.gradleBuild.build(this.taskName).task(":" + this.taskName)
.getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
try (JarFile jarFile = new JarFile(
new File(this.gradleBuild.getProjectDir(), "build/libs")
.listFiles()[0])) {
assertThat(jarFile.getManifest().getMainAttributes().getValue("Start-Class"))
.isEqualTo("com.example.CustomMain");
}
}
} }

View File

@ -66,6 +66,24 @@ public class BootRunIntegrationTests {
assertThat(result.getOutput()).doesNotContain(urlOf("build/resources/main")); assertThat(result.getOutput()).doesNotContain(urlOf("build/resources/main"));
} }
@Test
public void applicationPluginMainClassNameIsUsed() throws IOException {
BuildResult result = this.gradleBuild.build("echoMainClassName");
assertThat(result.task(":echoMainClassName").getOutcome())
.isEqualTo(TaskOutcome.UP_TO_DATE);
assertThat(result.getOutput())
.contains("Main class name = com.example.CustomMainClass");
}
@Test
public void applicationPluginJvmArgumentsAreUsed() throws IOException {
BuildResult result = this.gradleBuild.build("echoJvmArguments");
assertThat(result.task(":echoJvmArguments").getOutcome())
.isEqualTo(TaskOutcome.UP_TO_DATE);
assertThat(result.getOutput())
.contains("JVM arguments = [-Dcom.foo=bar, -Dcom.bar=baz]");
}
private String urlOf(String path) throws IOException { private String urlOf(String path) throws IOException {
return new File(this.gradleBuild.getProjectDir().getCanonicalFile(), path).toURI() return new File(this.gradleBuild.getProjectDir().getCanonicalFile(), path).toURI()
.toURL().toString(); .toURL().toString();

View File

@ -0,0 +1,11 @@
buildscript {
dependencies {
classpath files(pluginClasspath.split(','))
}
}
apply plugin: 'java'
apply plugin: 'org.springframework.boot'
apply plugin: 'application'
mainClassName = 'com.example.CustomMain'

View File

@ -0,0 +1,11 @@
buildscript {
dependencies {
classpath files(pluginClasspath.split(','))
}
}
apply plugin: 'war'
apply plugin: 'org.springframework.boot'
apply plugin: 'application'
mainClassName = 'com.example.CustomMain'

View File

@ -0,0 +1,14 @@
buildscript {
dependencies {
classpath files(pluginClasspath.split(','))
}
}
apply plugin: 'application'
apply plugin: 'org.springframework.boot'
applicationDefaultJvmArgs = ['-Dcom.foo=bar', '-Dcom.bar=baz']
task echoJvmArguments {
println 'JVM arguments = ' + bootRun.jvmArgs
}

View File

@ -0,0 +1,14 @@
buildscript {
dependencies {
classpath files(pluginClasspath.split(','))
}
}
apply plugin: 'application'
apply plugin: 'org.springframework.boot'
mainClassName = 'com.example.CustomMainClass'
task echoMainClassName {
println 'Main class name = ' + bootRun.main
}