Use mainClassName consistently across BootRun, BootJar, and BootWar

Previously, BootRun used the main property to configure the name of
the main class to run while BootJar and BootWar used the mainClass
property. Both were different to the application plugin which provides
a mainClassName project property.

This commit updates BootRun, BootJar, and BootWar to change the name
of the property used to configure the name of the main class to be
mainClassName. This makes the three Boot-specific tasks consistent
with each other, and also aligns them with Gradle's own application
plugin.

Closes gh-10622
This commit is contained in:
Andy Wilkinson 2017-10-19 12:11:04 +01:00
parent 671bff2d6f
commit 5502aaafd1
38 changed files with 88 additions and 87 deletions

View File

@ -85,7 +85,8 @@ By default, the executable archive's main class will be configured automatically
looking for a class with a `public static void main(String[])` method in directories on
the task's classpath.
The main class can also be configured explicitly using the task's `mainClass` property:
The main class can also be configured explicitly using the task's `mainClassName`
property:
[source,groovy,indent=0,subs="verbatim"]
----

View File

@ -11,8 +11,8 @@ To run your application without first building an archive use the `bootRun` task
The `bootRun` task is automatically configured to use the runtime classpath of the
main source set. By default, the main class will be discovered by looking for a class
with a `public static void main(String[])` method in directories on the task's
classpath. The main class can also be configured explicitly using the task's `main`
property:
classpath. The main class can also be configured explicitly using the task's
`mainClassName` property:
[source,groovy,indent=0,subs="verbatim"]
----

View File

@ -20,5 +20,5 @@ bootJar {
// end::classifier[]
bootJar {
mainClass = 'com.example.Application'
mainClassName = 'com.example.Application'
}

View File

@ -8,7 +8,7 @@ apply plugin: 'org.springframework.boot'
apply plugin: 'java'
bootJar {
mainClass 'com.example.ExampleApplication'
mainClassName 'com.example.ExampleApplication'
}
// tag::custom-launch-script[]

View File

@ -8,7 +8,7 @@ apply plugin: 'org.springframework.boot'
apply plugin: 'java'
bootJar {
mainClass 'com.example.ExampleApplication'
mainClassName 'com.example.ExampleApplication'
}
// tag::include-launch-script[]

View File

@ -8,7 +8,7 @@ apply plugin: 'org.springframework.boot'
apply plugin: 'java'
bootJar {
mainClass 'com.example.ExampleApplication'
mainClassName 'com.example.ExampleApplication'
}
// tag::launch-script-properties[]

View File

@ -9,6 +9,6 @@ apply plugin: 'java'
// tag::main-class[]
bootJar {
mainClass = 'com.example.ExampleApplication'
mainClassName = 'com.example.ExampleApplication'
}
// end::main-class[]

View File

@ -16,7 +16,7 @@ dependencies {
}
bootJar {
mainClass 'com.example.ExampleApplication'
mainClassName 'com.example.ExampleApplication'
}
// tag::requires-unpack[]

View File

@ -8,7 +8,7 @@ apply plugin: 'org.springframework.boot'
apply plugin: 'war'
bootWar {
mainClass 'com.example.ExampleApplication'
mainClassName 'com.example.ExampleApplication'
classpath file('spring-boot-devtools-1.2.3.RELEASE.jar')
}

View File

@ -8,7 +8,7 @@ apply plugin: 'org.springframework.boot'
apply plugin: 'war'
bootWar {
mainClass 'com.example.ExampleApplication'
mainClassName 'com.example.ExampleApplication'
}
// tag::properties-launcher[]

View File

@ -14,6 +14,6 @@ mainClassName = 'com.example.ExampleApplication'
task configuredMainClass {
doLast {
println bootRun.main
println bootRun.mainClassName
}
}

View File

@ -9,12 +9,12 @@ apply plugin: 'java'
// tag::main[]
bootRun {
main = 'com.example.ExampleApplication'
mainClassName = 'com.example.ExampleApplication'
}
// end::main[]
task configuredMainClass {
doLast {
println bootRun.main
println bootRun.mainClassName
}
}

View File

@ -87,7 +87,7 @@ final class JavaPluginAction implements PluginApplicationAction {
.getByName(SourceSet.MAIN_SOURCE_SET_NAME);
return mainSourceSet.getRuntimeClasspath();
});
bootJar.conventionMapping("mainClass",
bootJar.conventionMapping("mainClassName",
new MainClassConvention(project, bootJar::getClasspath));
return bootJar;
}
@ -112,7 +112,7 @@ final class JavaPluginAction implements PluginApplicationAction {
}
return Collections.emptyList();
}));
run.setMain(
run.setMainClassName(
project.provider(new MainClassConvention(project, run::getClasspath)));
}

View File

@ -55,7 +55,7 @@ class WarPluginAction implements PluginApplicationAction {
bootWar.providedClasspath(providedRuntimeConfiguration(project));
ArchivePublishArtifact artifact = new ArchivePublishArtifact(bootWar);
this.singlePublishedArtifact.addCandidate(artifact);
bootWar.conventionMapping("mainClass",
bootWar.conventionMapping("mainClassName",
new MainClassConvention(project, bootWar::getClasspath));
}

View File

@ -35,20 +35,20 @@ import org.gradle.api.tasks.Optional;
public interface BootArchive extends Task {
/**
* Returns the main class of the application.
* Returns the name of the main class of the application.
*
* @return the main class
* @return the main class name
*/
@Input
@Optional
String getMainClass();
String getMainClassName();
/**
* Sets the main class of the application.
* Sets the name of the main class of the application.
*
* @param mainClass the main class of the application
* @param mainClassName the name of the main class of the application
*/
void setMainClass(String mainClass);
void setMainClassName(String mainClassName);
/**
* Adds Ant-style patterns that identify files that must be unpacked from the archive

View File

@ -73,10 +73,10 @@ class BootArchiveSupport {
configureExclusions();
}
void configureManifest(Jar jar, String mainClass) {
void configureManifest(Jar jar, String mainClassName) {
Attributes attributes = jar.getManifest().getAttributes();
attributes.putIfAbsent("Main-Class", this.loaderMainClass);
attributes.putIfAbsent("Start-Class", mainClass);
attributes.putIfAbsent("Start-Class", mainClassName);
}
CopyAction createCopyAction(Jar jar) {

View File

@ -42,7 +42,7 @@ public class BootJar extends Jar implements BootArchive {
private FileCollection classpath;
private String mainClass;
private String mainClassName;
/**
* Creates a new {@code BootJar} task.
@ -63,7 +63,7 @@ public class BootJar extends Jar implements BootArchive {
@Override
public void copy() {
this.support.configureManifest(this, getMainClass());
this.support.configureManifest(this, getMainClassName());
super.copy();
}
@ -73,13 +73,13 @@ public class BootJar extends Jar implements BootArchive {
}
@Override
public String getMainClass() {
return this.mainClass;
public String getMainClassName() {
return this.mainClassName;
}
@Override
public void setMainClass(String mainClass) {
this.mainClass = mainClass;
public void setMainClassName(String mainClassName) {
this.mainClassName = mainClassName;
}
@Override

View File

@ -41,7 +41,7 @@ public class BootWar extends War implements BootArchive {
private final BootArchiveSupport support = new BootArchiveSupport(
"org.springframework.boot.loader.WarLauncher", this::resolveZipCompression);
private String mainClass;
private String mainClassName;
private FileCollection providedClasspath;
@ -57,7 +57,7 @@ public class BootWar extends War implements BootArchive {
@Override
public void copy() {
this.support.configureManifest(this, getMainClass());
this.support.configureManifest(this, getMainClassName());
super.copy();
}
@ -67,13 +67,13 @@ public class BootWar extends War implements BootArchive {
}
@Override
public String getMainClass() {
return this.mainClass;
public String getMainClassName() {
return this.mainClassName;
}
@Override
public void setMainClass(String mainClass) {
this.mainClass = mainClass;
public void setMainClassName(String mainClass) {
this.mainClassName = mainClass;
}
@Override

View File

@ -40,7 +40,7 @@ import org.gradle.process.JavaExecSpec;
*/
public class BootRun extends DefaultTask {
private final PropertyState<String> main = getProject().property(String.class);
private final PropertyState<String> mainClassName = getProject().property(String.class);
@SuppressWarnings("unchecked")
private final PropertyState<List<String>> jvmArgs = (PropertyState<List<String>>) (Object) getProject()
@ -85,26 +85,26 @@ public class BootRun extends DefaultTask {
* Returns the name of the main class to be run.
* @return the main class name or {@code null}
*/
public String getMain() {
return this.main.getOrNull();
public String getMainClassName() {
return this.mainClassName.getOrNull();
}
/**
* Sets the main class to be executed using the given {@code mainProvider}.
* Sets the name of the main class to be executed using the given {@code mainClassNameProvider}.
*
* @param mainProvider provider of the main class name
* @param mainClassNameProvider provider of the main class name
*/
public void setMain(Provider<String> mainProvider) {
this.main.set(mainProvider);
public void setMainClassName(Provider<String> mainClassNameProvider) {
this.mainClassName.set(mainClassNameProvider);
}
/**
* Sets the main class to be run.
* Sets the name of the main class to be run.
*
* @param main the main class name
* @param mainClassName the main class name
*/
public void setMain(String main) {
this.main.set(main);
public void setMainClassName(String mainClassName) {
this.mainClassName.set(mainClassName);
}
/**
@ -171,7 +171,7 @@ public class BootRun extends DefaultTask {
public void run() {
getProject().javaexec((spec) -> {
spec.classpath(this.classpath);
spec.setMain(this.main.getOrNull());
spec.setMain(this.mainClassName.getOrNull());
if (this.jvmArgs.isPresent()) {
spec.setJvmArgs(this.jvmArgs.get());
}

View File

@ -89,7 +89,7 @@ public abstract class AbstractBootArchiveTests<T extends Jar & BootArchive> {
@Test
public void basicArchiveCreation() throws IOException {
this.task.setMainClass("com.example.Main");
this.task.setMainClassName("com.example.Main");
this.task.execute();
assertThat(this.task.getArchivePath().exists());
try (JarFile jarFile = new JarFile(this.task.getArchivePath())) {
@ -102,7 +102,7 @@ public abstract class AbstractBootArchiveTests<T extends Jar & BootArchive> {
@Test
public void classpathJarsArePackagedBeneathLibPath() throws IOException {
this.task.setMainClass("com.example.Main");
this.task.setMainClassName("com.example.Main");
this.task.classpath(this.temp.newFile("one.jar"), this.temp.newFile("two.jar"));
this.task.execute();
try (JarFile jarFile = new JarFile(this.task.getArchivePath())) {
@ -113,7 +113,7 @@ public abstract class AbstractBootArchiveTests<T extends Jar & BootArchive> {
@Test
public void classpathFoldersArePackagedBeneathClassesPath() throws IOException {
this.task.setMainClass("com.example.Main");
this.task.setMainClassName("com.example.Main");
File classpathFolder = this.temp.newFolder();
File applicationClass = new File(classpathFolder,
"com/example/Application.class");
@ -130,7 +130,7 @@ public abstract class AbstractBootArchiveTests<T extends Jar & BootArchive> {
@Test
public void loaderIsWrittenToTheRootOfTheJar() throws IOException {
this.task.setMainClass("com.example.Main");
this.task.setMainClassName("com.example.Main");
this.task.execute();
try (JarFile jarFile = new JarFile(this.task.getArchivePath())) {
assertThat(jarFile.getEntry(
@ -143,7 +143,7 @@ public abstract class AbstractBootArchiveTests<T extends Jar & BootArchive> {
@Test
public void loaderIsWrittenToTheRootOfTheJarWhenUsingThePropertiesLauncher()
throws IOException {
this.task.setMainClass("com.example.Main");
this.task.setMainClassName("com.example.Main");
this.task.execute();
this.task.getManifest().getAttributes().put("Main-Class",
"org.springframework.boot.loader.PropertiesLauncher");
@ -157,7 +157,7 @@ public abstract class AbstractBootArchiveTests<T extends Jar & BootArchive> {
@Test
public void unpackCommentIsAddedToEntryIdentifiedByAPattern() throws IOException {
this.task.setMainClass("com.example.Main");
this.task.setMainClassName("com.example.Main");
this.task.classpath(this.temp.newFile("one.jar"), this.temp.newFile("two.jar"));
this.task.requiresUnpack("**/one.jar");
this.task.execute();
@ -170,7 +170,7 @@ public abstract class AbstractBootArchiveTests<T extends Jar & BootArchive> {
@Test
public void unpackCommentIsAddedToEntryIdentifiedByASpec() throws IOException {
this.task.setMainClass("com.example.Main");
this.task.setMainClassName("com.example.Main");
this.task.classpath(this.temp.newFile("one.jar"), this.temp.newFile("two.jar"));
this.task.requiresUnpack((element) -> element.getName().endsWith("two.jar"));
this.task.execute();
@ -183,7 +183,7 @@ public abstract class AbstractBootArchiveTests<T extends Jar & BootArchive> {
@Test
public void launchScriptCanBePrepended() throws IOException {
this.task.setMainClass("com.example.Main");
this.task.setMainClassName("com.example.Main");
this.task.launchScript();
this.task.execute();
assertThat(Files.readAllBytes(this.task.getArchivePath().toPath()))
@ -200,7 +200,7 @@ public abstract class AbstractBootArchiveTests<T extends Jar & BootArchive> {
@Test
public void customLaunchScriptCanBePrepended() throws IOException {
this.task.setMainClass("com.example.Main");
this.task.setMainClassName("com.example.Main");
File customScript = this.temp.newFile("custom.script");
Files.write(customScript.toPath(), Arrays.asList("custom script"),
StandardOpenOption.CREATE);
@ -212,7 +212,7 @@ public abstract class AbstractBootArchiveTests<T extends Jar & BootArchive> {
@Test
public void launchScriptPropertiesAreReplaced() throws IOException {
this.task.setMainClass("com.example.Main");
this.task.setMainClassName("com.example.Main");
this.task.launchScript((configuration) -> configuration.getProperties()
.put("initInfoProvides", "test property value"));
this.task.execute();
@ -222,7 +222,7 @@ public abstract class AbstractBootArchiveTests<T extends Jar & BootArchive> {
@Test
public void customMainClassInTheManifestIsHonored() throws IOException {
this.task.setMainClass("com.example.Main");
this.task.setMainClassName("com.example.Main");
this.task.getManifest().getAttributes().put("Main-Class",
"com.example.CustomLauncher");
this.task.execute();
@ -240,7 +240,7 @@ public abstract class AbstractBootArchiveTests<T extends Jar & BootArchive> {
@Test
public void customStartClassInTheManifestIsHonored() throws IOException {
this.task.setMainClass("com.example.Main");
this.task.setMainClassName("com.example.Main");
this.task.getManifest().getAttributes().put("Start-Class",
"com.example.CustomMain");
this.task.execute();
@ -255,7 +255,7 @@ public abstract class AbstractBootArchiveTests<T extends Jar & BootArchive> {
@Test
public void fileTimestampPreservationCanBeDisabled() throws IOException {
this.task.setMainClass("com.example.Main");
this.task.setMainClassName("com.example.Main");
this.task.setPreserveFileTimestamps(false);
this.task.execute();
assertThat(this.task.getArchivePath().exists());
@ -271,7 +271,7 @@ public abstract class AbstractBootArchiveTests<T extends Jar & BootArchive> {
@Test
public void reproducibleOrderingCanBeEnabled() throws IOException {
this.task.setMainClass("com.example.Main");
this.task.setMainClassName("com.example.Main");
this.task.from(this.temp.newFile("bravo.txt"), this.temp.newFile("alpha.txt"),
this.temp.newFile("charlie.txt"));
this.task.setReproducibleFileOrder(true);
@ -292,7 +292,7 @@ public abstract class AbstractBootArchiveTests<T extends Jar & BootArchive> {
@Test
public void devtoolsJarIsExcludedByDefault() throws IOException {
this.task.setMainClass("com.example.Main");
this.task.setMainClassName("com.example.Main");
this.task.classpath(this.temp.newFile("spring-boot-devtools-0.1.2.jar"));
this.task.execute();
assertThat(this.task.getArchivePath().exists());
@ -304,7 +304,7 @@ public abstract class AbstractBootArchiveTests<T extends Jar & BootArchive> {
@Test
public void devtoolsJarCanBeIncluded() throws IOException {
this.task.setMainClass("com.example.Main");
this.task.setMainClassName("com.example.Main");
this.task.classpath(this.temp.newFile("spring-boot-devtools-0.1.2.jar"));
this.task.setExcludeDevtools(false);
this.task.execute();
@ -317,7 +317,7 @@ public abstract class AbstractBootArchiveTests<T extends Jar & BootArchive> {
@Test
public void allEntriesUseUnixPlatformAndUtf8NameEncoding() throws IOException {
this.task.setMainClass("com.example.Main");
this.task.setMainClassName("com.example.Main");
this.task.setMetadataCharset("UTF-8");
File classpathFolder = this.temp.newFolder();
File resource = new File(classpathFolder, "some-resource.xml");

View File

@ -38,7 +38,7 @@ public class BootWarTests extends AbstractBootArchiveTests<BootWar> {
@Test
public void providedClasspathJarsArePackagedInWebInfLibProvided() throws IOException {
getTask().setMainClass("com.example.Main");
getTask().setMainClassName("com.example.Main");
getTask().providedClasspath(this.temp.newFile("one.jar"),
this.temp.newFile("two.jar"));
getTask().execute();
@ -51,7 +51,7 @@ public class BootWarTests extends AbstractBootArchiveTests<BootWar> {
@Test
public void devtoolsJarIsExcludedByDefaultWhenItsOnTheProvidedClasspath()
throws IOException {
getTask().setMainClass("com.example.Main");
getTask().setMainClassName("com.example.Main");
getTask().providedClasspath(this.temp.newFile("spring-boot-devtools-0.1.2.jar"));
getTask().execute();
assertThat(getTask().getArchivePath().exists());
@ -65,7 +65,7 @@ public class BootWarTests extends AbstractBootArchiveTests<BootWar> {
@Test
public void devtoolsJarCanBeIncludedWhenItsOnTheProvidedClasspath()
throws IOException {
getTask().setMainClass("com.example.Main");
getTask().setMainClassName("com.example.Main");
getTask().providedClasspath(this.temp.newFile("spring-boot-devtools-0.1.2.jar"));
getTask().setExcludeDevtools(false);
getTask().execute();
@ -85,7 +85,7 @@ public class BootWarTests extends AbstractBootArchiveTests<BootWar> {
orgFolder.mkdir();
new File(orgFolder, "foo.txt").createNewFile();
getTask().from(webappFolder);
getTask().setMainClass("com.example.Main");
getTask().setMainClassName("com.example.Main");
getTask().execute();
assertThat(getTask().getArchivePath().exists());
try (JarFile jarFile = new JarFile(getTask().getArchivePath())) {

View File

@ -9,5 +9,5 @@ apply plugin: 'application'
apply plugin: 'java'
bootJar {
mainClass = 'com.example.ExampleApplication'
mainClassName = 'com.example.ExampleApplication'
}

View File

@ -9,5 +9,5 @@ apply plugin: 'application'
apply plugin: 'war'
bootWar {
mainClass = 'com.example.ExampleApplication'
mainClassName = 'com.example.ExampleApplication'
}

View File

@ -9,5 +9,5 @@ apply plugin: 'application'
apply plugin: 'java'
bootJar {
mainClass = 'com.example.ExampleApplication'
mainClassName = 'com.example.ExampleApplication'
}

View File

@ -9,5 +9,5 @@ apply plugin: 'application'
apply plugin: 'war'
bootWar {
mainClass = 'com.example.ExampleApplication'
mainClassName = 'com.example.ExampleApplication'
}

View File

@ -8,5 +8,5 @@ apply plugin: 'org.springframework.boot'
apply plugin: 'java'
bootJar {
mainClass = 'com.example.Application'
mainClassName = 'com.example.Application'
}

View File

@ -8,7 +8,7 @@ apply plugin: 'org.springframework.boot'
apply plugin: 'java'
bootJar {
mainClass = 'com.example.Application'
mainClassName = 'com.example.Application'
classifier = 'boot'
}

View File

@ -8,5 +8,5 @@ apply plugin: 'org.springframework.boot'
apply plugin: 'war'
bootWar {
mainClass = 'com.example.Application'
mainClassName = 'com.example.Application'
}

View File

@ -8,7 +8,7 @@ apply plugin: 'org.springframework.boot'
apply plugin: 'war'
bootWar {
mainClass = 'com.example.Application'
mainClassName = 'com.example.Application'
classifier = 'boot'
}

View File

@ -8,7 +8,7 @@ apply plugin: 'java'
apply plugin: 'org.springframework.boot'
bootJar {
mainClass = 'com.example.CustomMain'
mainClassName = 'com.example.CustomMain'
duplicatesStrategy = "exclude"
}

View File

@ -8,7 +8,7 @@ apply plugin: 'java'
apply plugin: 'org.springframework.boot'
bootJar {
mainClass = 'com.example.Application'
mainClassName = 'com.example.Application'
if (project.hasProperty('includeLaunchScript') ? includeLaunchScript : false) {
launchScript {
properties 'prop' : project.hasProperty('launchScriptProperty') ? launchScriptProperty : 'default'

View File

@ -8,7 +8,7 @@ apply plugin: 'war'
apply plugin: 'org.springframework.boot'
bootWar {
mainClass = 'com.example.Application'
mainClassName = 'com.example.Application'
if (project.hasProperty('includeLaunchScript') ? includeLaunchScript : false) {
launchScript {
properties 'prop' : project.hasProperty('launchScriptProperty') ? launchScriptProperty : 'default'

View File

@ -9,7 +9,7 @@ apply plugin: 'org.springframework.boot'
apply plugin: 'maven'
bootJar {
mainClass = 'com.example.Application'
mainClassName = 'com.example.Application'
}
group = 'com.example'

View File

@ -9,7 +9,7 @@ apply plugin: 'org.springframework.boot'
apply plugin: 'maven'
bootWar {
mainClass = 'com.example.Application'
mainClassName = 'com.example.Application'
}
group = 'com.example'

View File

@ -9,7 +9,7 @@ apply plugin: 'org.springframework.boot'
apply plugin: 'maven-publish'
bootJar {
mainClass = 'com.example.Application'
mainClassName = 'com.example.Application'
}
group = 'com.example'

View File

@ -9,7 +9,7 @@ apply plugin: 'org.springframework.boot'
apply plugin: 'maven-publish'
bootWar {
mainClass = 'com.example.Application'
mainClassName = 'com.example.Application'
}
group = 'com.example'

View File

@ -10,6 +10,6 @@ apply plugin: 'org.springframework.boot'
task echoMainClassName {
dependsOn compileJava
doLast {
println 'Main class name = ' + bootRun.main
println 'Main class name = ' + bootRun.mainClassName
}
}

View File

@ -10,5 +10,5 @@ apply plugin: 'org.springframework.boot'
mainClassName = 'com.example.CustomMainClass'
task echoMainClassName {
println 'Main class name = ' + bootRun.main
println 'Main class name = ' + bootRun.mainClassName
}