Use Property<String>s for main class configuration in the Gradle plugin

Closes gh-23608
pull/23628/head
Andy Wilkinson 4 years ago
parent 91acd957b2
commit 70ed7784a6

@ -91,7 +91,7 @@ A number of configuration options that are specific to executable jars and wars
==== Configuring the Main Class ==== Configuring the Main Class
By default, the executable archive's main class will be configured automatically by looking for a class with a `public static void main(String[])` method in directories on the task's classpath. By default, the executable archive's main class will be configured automatically 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 `mainClassName` property: The main class can also be configured explicitly using the task's `mainClass` property:
[source,groovy,indent=0,subs="verbatim,attributes",role="primary"] [source,groovy,indent=0,subs="verbatim,attributes",role="primary"]
.Groovy .Groovy
@ -105,7 +105,7 @@ include::../gradle/packaging/boot-jar-main-class.gradle[tags=main-class]
include::../gradle/packaging/boot-jar-main-class.gradle.kts[tags=main-class] include::../gradle/packaging/boot-jar-main-class.gradle.kts[tags=main-class]
---- ----
Alternatively, the main class name can be configured project-wide using the `mainClassName` property of the Spring Boot DSL: Alternatively, the main class name can be configured project-wide using the `mainClass` property of the Spring Boot DSL:
[source,groovy,indent=0,subs="verbatim,attributes",role="primary"] [source,groovy,indent=0,subs="verbatim,attributes",role="primary"]
.Groovy .Groovy

@ -27,7 +27,7 @@ include::../gradle/running/boot-run-main.gradle[tags=main]
include::../gradle/running/boot-run-main.gradle.kts[tags=main] include::../gradle/running/boot-run-main.gradle.kts[tags=main]
---- ----
Alternatively, the main class name can be configured project-wide using the `mainClassName` property of the Spring Boot DSL: Alternatively, the main class name can be configured project-wide using the `mainClass` property of the Spring Boot DSL:
[source,groovy,indent=0,subs="verbatim,attributes",role="primary"] [source,groovy,indent=0,subs="verbatim,attributes",role="primary"]
.Groovy .Groovy

@ -4,7 +4,7 @@ plugins {
} }
bootJar { bootJar {
mainClassName 'com.example.ExampleApplication' mainClass = 'com.example.ExampleApplication'
} }
// tag::builder[] // tag::builder[]

@ -6,7 +6,7 @@ plugins {
} }
tasks.getByName<BootJar>("bootJar") { tasks.getByName<BootJar>("bootJar") {
mainClassName = "com.example.ExampleApplication" mainClass.set("com.example.ExampleApplication")
} }
// tag::builder[] // tag::builder[]

@ -4,7 +4,7 @@ plugins {
} }
bootJar { bootJar {
mainClassName 'com.example.ExampleApplication' mainClass = 'com.example.ExampleApplication'
} }
// tag::docker-auth-token[] // tag::docker-auth-token[]

@ -7,7 +7,7 @@ plugins {
} }
tasks.getByName<BootJar>("bootJar") { tasks.getByName<BootJar>("bootJar") {
mainClassName = "com.example.ExampleApplication" mainClass.set("com.example.ExampleApplication")
} }
// tag::docker-auth-token[] // tag::docker-auth-token[]

@ -4,7 +4,7 @@ plugins {
} }
bootJar { bootJar {
mainClassName 'com.example.ExampleApplication' mainClass = 'com.example.ExampleApplication'
} }
// tag::docker-auth-user[] // tag::docker-auth-user[]

@ -7,7 +7,7 @@ plugins {
} }
tasks.getByName<BootJar>("bootJar") { tasks.getByName<BootJar>("bootJar") {
mainClassName = "com.example.ExampleApplication" mainClass.set("com.example.ExampleApplication")
} }
// tag::docker-auth-user[] // tag::docker-auth-user[]

@ -4,7 +4,7 @@ plugins {
} }
bootJar { bootJar {
mainClassName 'com.example.ExampleApplication' mainClass = 'com.example.ExampleApplication'
} }
// tag::docker-host[] // tag::docker-host[]

@ -7,7 +7,7 @@ plugins {
} }
tasks.getByName<BootJar>("bootJar") { tasks.getByName<BootJar>("bootJar") {
mainClassName = "com.example.ExampleApplication" mainClass.set("com.example.ExampleApplication")
} }
// tag::docker-host[] // tag::docker-host[]

@ -3,10 +3,6 @@ plugins {
id 'org.springframework.boot' version '{gradle-project-version}' id 'org.springframework.boot' version '{gradle-project-version}'
} }
bootJar {
mainClassName 'com.example.ExampleApplication'
}
// tag::env[] // tag::env[]
bootBuildImage { bootBuildImage {
environment = [ environment = [

@ -3,10 +3,6 @@ plugins {
id 'org.springframework.boot' version '{gradle-project-version}' id 'org.springframework.boot' version '{gradle-project-version}'
} }
bootJar {
mainClassName 'com.example.ExampleApplication'
}
// tag::env[] // tag::env[]
bootBuildImage { bootBuildImage {
environment = ["BP_JVM_VERSION" : "8.*"] environment = ["BP_JVM_VERSION" : "8.*"]

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

@ -18,5 +18,5 @@ tasks.getByName<BootJar>("bootJar") {
// end::classifier[] // end::classifier[]
tasks.getByName<BootJar>("bootJar") { tasks.getByName<BootJar>("bootJar") {
mainClassName = "com.example.Application" mainClass.set("com.example.Application")
} }

@ -4,7 +4,7 @@ plugins {
} }
bootJar { bootJar {
mainClassName 'com.example.ExampleApplication' mainClass = 'com.example.ExampleApplication'
} }
// tag::custom-launch-script[] // tag::custom-launch-script[]

@ -6,7 +6,7 @@ plugins {
} }
tasks.getByName<BootJar>("bootJar") { tasks.getByName<BootJar>("bootJar") {
mainClassName = "com.example.ExampleApplication" mainClass.set("com.example.ExampleApplication")
} }
// tag::custom-launch-script[] // tag::custom-launch-script[]

@ -4,7 +4,7 @@ plugins {
} }
bootJar { bootJar {
mainClassName 'com.example.ExampleApplication' mainClass = 'com.example.ExampleApplication'
} }
// tag::include-launch-script[] // tag::include-launch-script[]

@ -6,7 +6,7 @@ plugins {
} }
tasks.getByName<BootJar>("bootJar") { tasks.getByName<BootJar>("bootJar") {
mainClassName = "com.example.ExampleApplication" mainClass.set("com.example.ExampleApplication")
} }
// tag::include-launch-script[] // tag::include-launch-script[]

@ -4,7 +4,7 @@ plugins {
} }
bootJar { bootJar {
mainClassName 'com.example.ExampleApplication' mainClass = 'com.example.ExampleApplication'
} }
// tag::launch-script-properties[] // tag::launch-script-properties[]

@ -6,7 +6,7 @@ plugins {
} }
tasks.getByName<BootJar>("bootJar") { tasks.getByName<BootJar>("bootJar") {
mainClassName = "com.example.ExampleApplication" mainClass.set("com.example.ExampleApplication")
} }
// tag::launch-script-properties[] // tag::launch-script-properties[]

@ -4,7 +4,7 @@ plugins {
} }
bootJar { bootJar {
mainClassName 'com.example.ExampleApplication' mainClass = 'com.example.ExampleApplication'
} }
// tag::layered[] // tag::layered[]

@ -6,7 +6,7 @@ plugins {
} }
tasks.getByName<BootJar>("bootJar") { tasks.getByName<BootJar>("bootJar") {
mainClassName = "com.example.ExampleApplication" mainClass.set("com.example.ExampleApplication")
} }
// tag::layered[] // tag::layered[]

@ -4,7 +4,7 @@ plugins {
} }
bootJar { bootJar {
mainClassName 'com.example.ExampleApplication' mainClass = 'com.example.ExampleApplication'
} }
// tag::layered[] // tag::layered[]

@ -6,7 +6,7 @@ plugins {
} }
tasks.getByName<BootJar>("bootJar") { tasks.getByName<BootJar>("bootJar") {
mainClassName = "com.example.ExampleApplication" mainClass.set("com.example.ExampleApplication")
} }
// tag::layered[] // tag::layered[]

@ -4,7 +4,7 @@ plugins {
} }
bootJar { bootJar {
mainClassName 'com.example.ExampleApplication' mainClass = 'com.example.ExampleApplication'
} }
// tag::layered[] // tag::layered[]

@ -6,7 +6,7 @@ plugins {
} }
tasks.getByName<BootJar>("bootJar") { tasks.getByName<BootJar>("bootJar") {
mainClassName = "com.example.ExampleApplication" mainClass.set("com.example.ExampleApplication")
} }
// tag::layered[] // tag::layered[]

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

@ -7,6 +7,6 @@ plugins {
// tag::main-class[] // tag::main-class[]
tasks.getByName<BootJar>("bootJar") { tasks.getByName<BootJar>("bootJar") {
mainClassName = "com.example.ExampleApplication" mainClass.set("com.example.ExampleApplication")
} }
// end::main-class[] // end::main-class[]

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

@ -14,7 +14,7 @@ dependencies {
} }
tasks.getByName<BootJar>("bootJar") { tasks.getByName<BootJar>("bootJar") {
mainClassName = "com.example.ExampleApplication" mainClass.set("com.example.ExampleApplication")
} }
// tag::requires-unpack[] // tag::requires-unpack[]

@ -4,7 +4,7 @@ plugins {
} }
bootWar { bootWar {
mainClassName 'com.example.ExampleApplication' mainClass = 'com.example.ExampleApplication'
} }
dependencies { dependencies {

@ -6,7 +6,7 @@ plugins {
} }
tasks.getByName<BootWar>("bootWar") { tasks.getByName<BootWar>("bootWar") {
mainClassName = "com.example.ExampleApplication" mainClass.set("com.example.ExampleApplication")
} }
dependencies { dependencies {

@ -4,7 +4,7 @@ plugins {
} }
bootWar { bootWar {
mainClassName 'com.example.ExampleApplication' mainClass = 'com.example.ExampleApplication'
} }
// tag::properties-launcher[] // tag::properties-launcher[]

@ -6,7 +6,7 @@ plugins {
} }
tasks.getByName<BootWar>("bootWar") { tasks.getByName<BootWar>("bootWar") {
mainClassName = "com.example.ExampleApplication" mainClass.set("com.example.ExampleApplication")
} }
// tag::properties-launcher[] // tag::properties-launcher[]

@ -5,6 +5,6 @@ plugins {
// tag::main-class[] // tag::main-class[]
springBoot { springBoot {
mainClassName = 'com.example.ExampleApplication' mainClass = 'com.example.ExampleApplication'
} }
// end::main-class[] // end::main-class[]

@ -5,6 +5,6 @@ plugins {
// tag::main-class[] // tag::main-class[]
springBoot { springBoot {
mainClassName = "com.example.ExampleApplication" mainClass.set("com.example.ExampleApplication")
} }
// end::main-class[] // end::main-class[]

@ -6,7 +6,7 @@ plugins {
// tag::main-class[] // tag::main-class[]
springBoot { springBoot {
mainClassName = 'com.example.ExampleApplication' mainClass = 'com.example.ExampleApplication'
} }
// end::main-class[] // end::main-class[]

@ -8,7 +8,7 @@ plugins {
// tag::main-class[] // tag::main-class[]
springBoot { springBoot {
mainClassName = "com.example.ExampleApplication" mainClass.set("com.example.ExampleApplication")
} }
// end::main-class[] // end::main-class[]

@ -20,9 +20,11 @@ import java.io.File;
import org.gradle.api.Action; import org.gradle.api.Action;
import org.gradle.api.Project; import org.gradle.api.Project;
import org.gradle.api.model.ReplacedBy;
import org.gradle.api.plugins.BasePlugin; import org.gradle.api.plugins.BasePlugin;
import org.gradle.api.plugins.JavaPlugin; import org.gradle.api.plugins.JavaPlugin;
import org.gradle.api.plugins.JavaPluginConvention; import org.gradle.api.plugins.JavaPluginConvention;
import org.gradle.api.provider.Property;
import org.gradle.api.tasks.SourceSet; import org.gradle.api.tasks.SourceSet;
import org.gradle.api.tasks.TaskContainer; import org.gradle.api.tasks.TaskContainer;
import org.gradle.api.tasks.TaskProvider; import org.gradle.api.tasks.TaskProvider;
@ -42,7 +44,7 @@ public class SpringBootExtension {
private final Project project; private final Project project;
private String mainClassName; private final Property<String> mainClass;
/** /**
* Creates a new {@code SpringBootPluginExtension} that is associated with the given * Creates a new {@code SpringBootPluginExtension} that is associated with the given
@ -51,22 +53,38 @@ public class SpringBootExtension {
*/ */
public SpringBootExtension(Project project) { public SpringBootExtension(Project project) {
this.project = project; this.project = project;
this.mainClass = this.project.getObjects().property(String.class);
} }
/** /**
* Returns the main class name of the application. * Returns the fully-qualified name of the application's main class.
* @return the name of the application's main class * @return the fully-qualified name of the application's main class
* @since 2.4.0
*/ */
public Property<String> getMainClass() {
return this.mainClass;
}
/**
* Returns the fully-qualified main class name of the application.
* @return the fully-qualified name of the application's main class
* @deprecated since 2.4.0 in favor of {@link #getMainClass()}.
*/
@Deprecated
@ReplacedBy("mainClass")
public String getMainClassName() { public String getMainClassName() {
return this.mainClassName; return this.mainClass.getOrNull();
} }
/** /**
* Sets the main class name of the application. * Sets the fully-qualified main class name of the application.
* @param mainClassName the name of the application's main class * @param mainClassName the fully-qualified name of the application's main class
* @deprecated since 2.4.0 in favour of {@link #getMainClass} and
* {@link Property#set(Object)}
*/ */
@Deprecated
public void setMainClassName(String mainClassName) { public void setMainClassName(String mainClassName) {
this.mainClassName = mainClassName; this.mainClass.set(mainClassName);
} }
/** /**

@ -107,7 +107,11 @@ final class JavaPluginAction implements PluginApplicationAction {
return mainSourceSet.getRuntimeClasspath().minus((developmentOnly.minus(productionRuntimeClasspath))) return mainSourceSet.getRuntimeClasspath().minus((developmentOnly.minus(productionRuntimeClasspath)))
.filter(new JarTypeFileSpec()); .filter(new JarTypeFileSpec());
}); });
bootJar.conventionMapping("mainClassName", new MainClassConvention(project, bootJar::getClasspath)); bootJar.getMainClass().convention(project.provider(() -> {
String manifestStartClass = (String) bootJar.getManifest().getAttributes().get("Start-Class");
return (manifestStartClass != null) ? manifestStartClass
: new MainClassConvention(project, bootJar::getClasspath).call();
}));
}); });
} }

@ -37,7 +37,7 @@ import org.springframework.boot.loader.tools.MainClassFinder;
* *
* @author Andy Wilkinson * @author Andy Wilkinson
*/ */
final class MainClassConvention implements Callable<Object> { final class MainClassConvention implements Callable<String> {
private static final String SPRING_BOOT_APPLICATION_CLASS_NAME = "org.springframework.boot.autoconfigure.SpringBootApplication"; private static final String SPRING_BOOT_APPLICATION_CLASS_NAME = "org.springframework.boot.autoconfigure.SpringBootApplication";
@ -51,10 +51,13 @@ final class MainClassConvention implements Callable<Object> {
} }
@Override @Override
public Object call() throws Exception { public String call() throws Exception {
SpringBootExtension springBootExtension = this.project.getExtensions().findByType(SpringBootExtension.class); SpringBootExtension springBootExtension = this.project.getExtensions().findByType(SpringBootExtension.class);
if (springBootExtension != null && springBootExtension.getMainClassName() != null) { if (springBootExtension != null) {
return springBootExtension.getMainClassName(); String mainClass = springBootExtension.getMainClass().getOrNull();
if (mainClass != null) {
return mainClass;
}
} }
String javaApplicationMainClass = getJavaApplicationMainClass(); String javaApplicationMainClass = getJavaApplicationMainClass();
return (javaApplicationMainClass != null) ? javaApplicationMainClass : resolveMainClass(); return (javaApplicationMainClass != null) ? javaApplicationMainClass : resolveMainClass();

@ -71,7 +71,11 @@ class WarPluginAction implements PluginApplicationAction {
.getByName(SpringBootPlugin.PRODUCTION_RUNTIME_CLASSPATH_NAME); .getByName(SpringBootPlugin.PRODUCTION_RUNTIME_CLASSPATH_NAME);
bootWar.setClasspath(bootWar.getClasspath().minus((developmentOnly.minus(productionRuntimeClasspath))) bootWar.setClasspath(bootWar.getClasspath().minus((developmentOnly.minus(productionRuntimeClasspath)))
.filter(new JarTypeFileSpec())); .filter(new JarTypeFileSpec()));
bootWar.conventionMapping("mainClassName", new MainClassConvention(project, bootWar::getClasspath)); bootWar.getMainClass().convention(project.provider(() -> {
String manifestStartClass = (String) bootWar.getManifest().getAttributes().get("Start-Class");
return (manifestStartClass != null) ? manifestStartClass
: new MainClassConvention(project, bootWar::getClasspath).call();
}));
}); });
} }

@ -21,6 +21,8 @@ import org.gradle.api.Project;
import org.gradle.api.Task; import org.gradle.api.Task;
import org.gradle.api.file.FileCollection; import org.gradle.api.file.FileCollection;
import org.gradle.api.file.FileTreeElement; import org.gradle.api.file.FileTreeElement;
import org.gradle.api.model.ReplacedBy;
import org.gradle.api.provider.Property;
import org.gradle.api.specs.Spec; import org.gradle.api.specs.Spec;
import org.gradle.api.tasks.Classpath; import org.gradle.api.tasks.Classpath;
import org.gradle.api.tasks.Input; import org.gradle.api.tasks.Input;
@ -35,16 +37,29 @@ import org.gradle.api.tasks.Optional;
public interface BootArchive extends Task { public interface BootArchive extends Task {
/** /**
* Returns the name of the main class of the application. * Returns the fully-qualified name of the application's main class.
* @return the main class name * @return the fully-qualified name of the application's main class
* @since 2.4.0
*/ */
@Input @Input
Property<String> getMainClass();
/**
* Returns the fully-qualified main class name of the application.
* @return the fully-qualified name of the application's main class
* @deprecated since 2.4.0 in favor of {@link #getMainClass()}.
*/
@Deprecated
@ReplacedBy("mainClass")
String getMainClassName(); String getMainClassName();
/** /**
* Sets the name of the main class of the application. * Sets the fully-qualified main class name of the application.
* @param mainClassName the name of the main class of the application * @param mainClassName the fully-qualified name of the application's main class
* @deprecated since 2.4.0 in favour of {@link #getMainClass} and
* {@link Property#set(Object)}
*/ */
@Deprecated
void setMainClassName(String mainClassName); void setMainClassName(String mainClassName);
/** /**

@ -28,6 +28,7 @@ import org.gradle.api.file.FileCollection;
import org.gradle.api.file.FileCopyDetails; import org.gradle.api.file.FileCopyDetails;
import org.gradle.api.file.FileTreeElement; import org.gradle.api.file.FileTreeElement;
import org.gradle.api.internal.file.copy.CopyAction; import org.gradle.api.internal.file.copy.CopyAction;
import org.gradle.api.provider.Property;
import org.gradle.api.specs.Spec; import org.gradle.api.specs.Spec;
import org.gradle.api.tasks.Internal; import org.gradle.api.tasks.Internal;
import org.gradle.api.tasks.Nested; import org.gradle.api.tasks.Nested;
@ -60,7 +61,7 @@ public class BootJar extends Jar implements BootArchive {
private final CopySpec bootInfSpec; private final CopySpec bootInfSpec;
private String mainClassName; private final Property<String> mainClass;
private FileCollection classpath; private FileCollection classpath;
@ -72,6 +73,7 @@ public class BootJar extends Jar implements BootArchive {
public BootJar() { public BootJar() {
this.support = new BootArchiveSupport(LAUNCHER, this::isLibrary, this::resolveZipCompression); this.support = new BootArchiveSupport(LAUNCHER, this::isLibrary, this::resolveZipCompression);
this.bootInfSpec = getProject().copySpec().into("BOOT-INF"); this.bootInfSpec = getProject().copySpec().into("BOOT-INF");
this.mainClass = getProject().getObjects().property(String.class);
configureBootInfSpec(this.bootInfSpec); configureBootInfSpec(this.bootInfSpec);
getMainSpec().with(this.bootInfSpec); getMainSpec().with(this.bootInfSpec);
getProject().getConfigurations().all((configuration) -> { getProject().getConfigurations().all((configuration) -> {
@ -102,7 +104,7 @@ public class BootJar extends Jar implements BootArchive {
@Override @Override
public void copy() { public void copy() {
this.support.configureManifest(getManifest(), getMainClassName(), CLASSES_DIRECTORY, LIB_DIRECTORY, this.support.configureManifest(getManifest(), getMainClass().get(), CLASSES_DIRECTORY, LIB_DIRECTORY,
CLASSPATH_INDEX, (isLayeredDisabled()) ? null : LAYERS_INDEX); CLASSPATH_INDEX, (isLayeredDisabled()) ? null : LAYERS_INDEX);
super.copy(); super.copy();
} }
@ -127,19 +129,20 @@ public class BootJar extends Jar implements BootArchive {
} }
@Override @Override
public String getMainClassName() { public Property<String> getMainClass() {
if (this.mainClassName == null) { return this.mainClass;
String manifestStartClass = (String) getManifest().getAttributes().get("Start-Class");
if (manifestStartClass != null) {
setMainClassName(manifestStartClass);
}
} }
return this.mainClassName;
@Override
@Deprecated
public String getMainClassName() {
return this.mainClass.getOrNull();
} }
@Override @Override
@Deprecated
public void setMainClassName(String mainClassName) { public void setMainClassName(String mainClassName) {
this.mainClassName = mainClassName; this.mainClass.set(mainClassName);
} }
@Override @Override

@ -26,6 +26,7 @@ import org.gradle.api.file.FileCollection;
import org.gradle.api.file.FileCopyDetails; import org.gradle.api.file.FileCopyDetails;
import org.gradle.api.file.FileTreeElement; import org.gradle.api.file.FileTreeElement;
import org.gradle.api.internal.file.copy.CopyAction; import org.gradle.api.internal.file.copy.CopyAction;
import org.gradle.api.provider.Property;
import org.gradle.api.specs.Spec; import org.gradle.api.specs.Spec;
import org.gradle.api.tasks.Classpath; import org.gradle.api.tasks.Classpath;
import org.gradle.api.tasks.Optional; import org.gradle.api.tasks.Optional;
@ -50,7 +51,7 @@ public class BootWar extends War implements BootArchive {
private final BootArchiveSupport support; private final BootArchiveSupport support;
private String mainClassName; private final Property<String> mainClass;
private FileCollection providedClasspath; private FileCollection providedClasspath;
@ -59,6 +60,7 @@ public class BootWar extends War implements BootArchive {
*/ */
public BootWar() { public BootWar() {
this.support = new BootArchiveSupport(LAUNCHER, this::isLibrary, this::resolveZipCompression); this.support = new BootArchiveSupport(LAUNCHER, this::isLibrary, this::resolveZipCompression);
this.mainClass = getProject().getObjects().property(String.class);
getWebInf().into("lib-provided", fromCallTo(this::getProvidedLibFiles)); getWebInf().into("lib-provided", fromCallTo(this::getProvidedLibFiles));
this.support.moveModuleInfoToRoot(getRootSpec()); this.support.moveModuleInfoToRoot(getRootSpec());
getRootSpec().eachFile(this.support::excludeNonZipLibraryFiles); getRootSpec().eachFile(this.support::excludeNonZipLibraryFiles);
@ -70,7 +72,8 @@ public class BootWar extends War implements BootArchive {
@Override @Override
public void copy() { public void copy() {
this.support.configureManifest(getManifest(), getMainClassName(), CLASSES_DIRECTORY, LIB_DIRECTORY, null, null); this.support.configureManifest(getManifest(), getMainClass().get(), CLASSES_DIRECTORY, LIB_DIRECTORY, null,
null);
super.copy(); super.copy();
} }
@ -80,19 +83,20 @@ public class BootWar extends War implements BootArchive {
} }
@Override @Override
public String getMainClassName() { public Property<String> getMainClass() {
if (this.mainClassName == null) { return this.mainClass;
String manifestStartClass = (String) getManifest().getAttributes().get("Start-Class");
if (manifestStartClass != null) {
setMainClassName(manifestStartClass);
}
} }
return this.mainClassName;
@Override
@Deprecated
public String getMainClassName() {
return this.mainClass.getOrNull();
} }
@Override @Override
public void setMainClassName(String mainClass) { @Deprecated
this.mainClassName = mainClass; public void setMainClassName(String mainClassName) {
this.mainClass.set(mainClassName);
} }
@Override @Override

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2019 the original author or authors. * Copyright 2012-2020 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -63,7 +63,7 @@ class MainClassConventionTests {
void springBootExtensionMainClassNameIsUsed() throws Exception { void springBootExtensionMainClassNameIsUsed() throws Exception {
SpringBootExtension extension = this.project.getExtensions().create("springBoot", SpringBootExtension.class, SpringBootExtension extension = this.project.getExtensions().create("springBoot", SpringBootExtension.class,
this.project); this.project);
extension.setMainClassName("com.example.MainClass"); extension.getMainClass().set("com.example.MainClass");
assertThat(this.convention.call()).isEqualTo("com.example.MainClass"); assertThat(this.convention.call()).isEqualTo("com.example.MainClass");
} }
@ -74,7 +74,7 @@ class MainClassConventionTests {
javaApplication.setMainClassName("com.example.JavaApplicationMainClass"); javaApplication.setMainClassName("com.example.JavaApplicationMainClass");
SpringBootExtension extension = this.project.getExtensions().create("springBoot", SpringBootExtension.class, SpringBootExtension extension = this.project.getExtensions().create("springBoot", SpringBootExtension.class,
this.project); this.project);
extension.setMainClassName("com.example.SpringBootExtensionMainClass"); extension.getMainClass().set("com.example.SpringBootExtensionMainClass");
assertThat(this.convention.call()).isEqualTo("com.example.SpringBootExtensionMainClass"); assertThat(this.convention.call()).isEqualTo("com.example.SpringBootExtensionMainClass");
} }

@ -99,7 +99,7 @@ abstract class AbstractBootArchiveTests<T extends Jar & BootArchive> {
@Test @Test
void basicArchiveCreation() throws IOException { void basicArchiveCreation() throws IOException {
this.task.setMainClassName("com.example.Main"); this.task.getMainClass().set("com.example.Main");
executeTask(); executeTask();
try (JarFile jarFile = new JarFile(this.task.getArchiveFile().get().getAsFile())) { try (JarFile jarFile = new JarFile(this.task.getArchiveFile().get().getAsFile())) {
assertThat(jarFile.getManifest().getMainAttributes().getValue("Main-Class")).isEqualTo(this.launcherClass); assertThat(jarFile.getManifest().getMainAttributes().getValue("Main-Class")).isEqualTo(this.launcherClass);
@ -113,7 +113,7 @@ abstract class AbstractBootArchiveTests<T extends Jar & BootArchive> {
@Test @Test
void classpathJarsArePackagedBeneathLibPathAndAreStored() throws IOException { void classpathJarsArePackagedBeneathLibPathAndAreStored() throws IOException {
this.task.setMainClassName("com.example.Main"); this.task.getMainClass().set("com.example.Main");
this.task.classpath(jarFile("one.jar"), jarFile("two.jar")); this.task.classpath(jarFile("one.jar"), jarFile("two.jar"));
executeTask(); executeTask();
try (JarFile jarFile = new JarFile(this.task.getArchiveFile().get().getAsFile())) { try (JarFile jarFile = new JarFile(this.task.getArchiveFile().get().getAsFile())) {
@ -126,7 +126,7 @@ abstract class AbstractBootArchiveTests<T extends Jar & BootArchive> {
@Test @Test
void classpathDirectoriesArePackagedBeneathClassesPath() throws IOException { void classpathDirectoriesArePackagedBeneathClassesPath() throws IOException {
this.task.setMainClassName("com.example.Main"); this.task.getMainClass().set("com.example.Main");
File classpathDirectory = new File(this.temp, "classes"); File classpathDirectory = new File(this.temp, "classes");
File applicationClass = new File(classpathDirectory, "com/example/Application.class"); File applicationClass = new File(classpathDirectory, "com/example/Application.class");
applicationClass.getParentFile().mkdirs(); applicationClass.getParentFile().mkdirs();
@ -140,7 +140,7 @@ abstract class AbstractBootArchiveTests<T extends Jar & BootArchive> {
@Test @Test
void moduleInfoClassIsPackagedInTheRootOfTheArchive() throws IOException { void moduleInfoClassIsPackagedInTheRootOfTheArchive() throws IOException {
this.task.setMainClassName("com.example.Main"); this.task.getMainClass().set("com.example.Main");
File classpathDirectory = new File(this.temp, "classes"); File classpathDirectory = new File(this.temp, "classes");
File moduleInfoClass = new File(classpathDirectory, "module-info.class"); File moduleInfoClass = new File(classpathDirectory, "module-info.class");
moduleInfoClass.getParentFile().mkdirs(); moduleInfoClass.getParentFile().mkdirs();
@ -160,7 +160,7 @@ abstract class AbstractBootArchiveTests<T extends Jar & BootArchive> {
@Test @Test
void classpathCanBeSetUsingAFileCollection() throws IOException { void classpathCanBeSetUsingAFileCollection() throws IOException {
this.task.setMainClassName("com.example.Main"); this.task.getMainClass().set("com.example.Main");
this.task.classpath(jarFile("one.jar")); this.task.classpath(jarFile("one.jar"));
this.task.setClasspath(this.task.getProject().files(jarFile("two.jar"))); this.task.setClasspath(this.task.getProject().files(jarFile("two.jar")));
executeTask(); executeTask();
@ -172,7 +172,7 @@ abstract class AbstractBootArchiveTests<T extends Jar & BootArchive> {
@Test @Test
void classpathCanBeSetUsingAnObject() throws IOException { void classpathCanBeSetUsingAnObject() throws IOException {
this.task.setMainClassName("com.example.Main"); this.task.getMainClass().set("com.example.Main");
this.task.classpath(jarFile("one.jar")); this.task.classpath(jarFile("one.jar"));
this.task.setClasspath(jarFile("two.jar")); this.task.setClasspath(jarFile("two.jar"));
executeTask(); executeTask();
@ -184,7 +184,7 @@ abstract class AbstractBootArchiveTests<T extends Jar & BootArchive> {
@Test @Test
void filesOnTheClasspathThatAreNotZipFilesAreSkipped() throws IOException { void filesOnTheClasspathThatAreNotZipFilesAreSkipped() throws IOException {
this.task.setMainClassName("com.example.Main"); this.task.getMainClass().set("com.example.Main");
this.task.classpath(new File("test.pom")); this.task.classpath(new File("test.pom"));
executeTask(); executeTask();
try (JarFile jarFile = new JarFile(this.task.getArchiveFile().get().getAsFile())) { try (JarFile jarFile = new JarFile(this.task.getArchiveFile().get().getAsFile())) {
@ -194,7 +194,7 @@ abstract class AbstractBootArchiveTests<T extends Jar & BootArchive> {
@Test @Test
void loaderIsWrittenToTheRootOfTheJarAfterManifest() throws IOException { void loaderIsWrittenToTheRootOfTheJarAfterManifest() throws IOException {
this.task.setMainClassName("com.example.Main"); this.task.getMainClass().set("com.example.Main");
executeTask(); executeTask();
try (JarFile jarFile = new JarFile(this.task.getArchiveFile().get().getAsFile())) { try (JarFile jarFile = new JarFile(this.task.getArchiveFile().get().getAsFile())) {
assertThat(jarFile.getEntry("org/springframework/boot/loader/LaunchedURLClassLoader.class")).isNotNull(); assertThat(jarFile.getEntry("org/springframework/boot/loader/LaunchedURLClassLoader.class")).isNotNull();
@ -210,7 +210,7 @@ abstract class AbstractBootArchiveTests<T extends Jar & BootArchive> {
@Test @Test
void loaderIsWrittenToTheRootOfTheJarWhenUsingThePropertiesLauncher() throws IOException { void loaderIsWrittenToTheRootOfTheJarWhenUsingThePropertiesLauncher() throws IOException {
this.task.setMainClassName("com.example.Main"); this.task.getMainClass().set("com.example.Main");
executeTask(); executeTask();
this.task.getManifest().getAttributes().put("Main-Class", "org.springframework.boot.loader.PropertiesLauncher"); this.task.getManifest().getAttributes().put("Main-Class", "org.springframework.boot.loader.PropertiesLauncher");
try (JarFile jarFile = new JarFile(this.task.getArchiveFile().get().getAsFile())) { try (JarFile jarFile = new JarFile(this.task.getArchiveFile().get().getAsFile())) {
@ -221,7 +221,7 @@ abstract class AbstractBootArchiveTests<T extends Jar & BootArchive> {
@Test @Test
void unpackCommentIsAddedToEntryIdentifiedByAPattern() throws IOException { void unpackCommentIsAddedToEntryIdentifiedByAPattern() throws IOException {
this.task.setMainClassName("com.example.Main"); this.task.getMainClass().set("com.example.Main");
this.task.classpath(jarFile("one.jar"), jarFile("two.jar")); this.task.classpath(jarFile("one.jar"), jarFile("two.jar"));
this.task.requiresUnpack("**/one.jar"); this.task.requiresUnpack("**/one.jar");
executeTask(); executeTask();
@ -233,7 +233,7 @@ abstract class AbstractBootArchiveTests<T extends Jar & BootArchive> {
@Test @Test
void unpackCommentIsAddedToEntryIdentifiedByASpec() throws IOException { void unpackCommentIsAddedToEntryIdentifiedByASpec() throws IOException {
this.task.setMainClassName("com.example.Main"); this.task.getMainClass().set("com.example.Main");
this.task.classpath(jarFile("one.jar"), jarFile("two.jar")); this.task.classpath(jarFile("one.jar"), jarFile("two.jar"));
this.task.requiresUnpack((element) -> element.getName().endsWith("two.jar")); this.task.requiresUnpack((element) -> element.getName().endsWith("two.jar"));
executeTask(); executeTask();
@ -245,7 +245,7 @@ abstract class AbstractBootArchiveTests<T extends Jar & BootArchive> {
@Test @Test
void launchScriptCanBePrepended() throws IOException { void launchScriptCanBePrepended() throws IOException {
this.task.setMainClassName("com.example.Main"); this.task.getMainClass().set("com.example.Main");
this.task.launchScript(); this.task.launchScript();
executeTask(); executeTask();
Map<String, String> properties = new HashMap<>(); Map<String, String> properties = new HashMap<>();
@ -266,7 +266,7 @@ abstract class AbstractBootArchiveTests<T extends Jar & BootArchive> {
@Test @Test
void customLaunchScriptCanBePrepended() throws IOException { void customLaunchScriptCanBePrepended() throws IOException {
this.task.setMainClassName("com.example.Main"); this.task.getMainClass().set("com.example.Main");
File customScript = new File(this.temp, "custom.script"); File customScript = new File(this.temp, "custom.script");
Files.write(customScript.toPath(), Arrays.asList("custom script"), StandardOpenOption.CREATE); Files.write(customScript.toPath(), Arrays.asList("custom script"), StandardOpenOption.CREATE);
this.task.launchScript((configuration) -> configuration.setScript(customScript)); this.task.launchScript((configuration) -> configuration.setScript(customScript));
@ -277,7 +277,7 @@ abstract class AbstractBootArchiveTests<T extends Jar & BootArchive> {
@Test @Test
void launchScriptInitInfoPropertiesCanBeCustomized() throws IOException { void launchScriptInitInfoPropertiesCanBeCustomized() throws IOException {
this.task.setMainClassName("com.example.Main"); this.task.getMainClass().set("com.example.Main");
this.task.launchScript((configuration) -> { this.task.launchScript((configuration) -> {
configuration.getProperties().put("initInfoProvides", "provides"); configuration.getProperties().put("initInfoProvides", "provides");
configuration.getProperties().put("initInfoShortDescription", "short description"); configuration.getProperties().put("initInfoShortDescription", "short description");
@ -292,7 +292,7 @@ abstract class AbstractBootArchiveTests<T extends Jar & BootArchive> {
@Test @Test
void customMainClassInTheManifestIsHonored() throws IOException { void customMainClassInTheManifestIsHonored() throws IOException {
this.task.setMainClassName("com.example.Main"); this.task.getMainClass().set("com.example.Main");
this.task.getManifest().getAttributes().put("Main-Class", "com.example.CustomLauncher"); this.task.getManifest().getAttributes().put("Main-Class", "com.example.CustomLauncher");
executeTask(); executeTask();
assertThat(this.task.getArchiveFile().get().getAsFile()).exists(); assertThat(this.task.getArchiveFile().get().getAsFile()).exists();
@ -306,7 +306,7 @@ abstract class AbstractBootArchiveTests<T extends Jar & BootArchive> {
@Test @Test
void customStartClassInTheManifestIsHonored() throws IOException { void customStartClassInTheManifestIsHonored() throws IOException {
this.task.setMainClassName("com.example.Main"); this.task.getMainClass().set("com.example.Main");
this.task.getManifest().getAttributes().put("Start-Class", "com.example.CustomMain"); this.task.getManifest().getAttributes().put("Start-Class", "com.example.CustomMain");
executeTask(); executeTask();
assertThat(this.task.getArchiveFile().get().getAsFile()).exists(); assertThat(this.task.getArchiveFile().get().getAsFile()).exists();
@ -319,7 +319,7 @@ abstract class AbstractBootArchiveTests<T extends Jar & BootArchive> {
@Test @Test
void fileTimestampPreservationCanBeDisabled() throws IOException { void fileTimestampPreservationCanBeDisabled() throws IOException {
this.task.setMainClassName("com.example.Main"); this.task.getMainClass().set("com.example.Main");
this.task.setPreserveFileTimestamps(false); this.task.setPreserveFileTimestamps(false);
executeTask(); executeTask();
assertThat(this.task.getArchiveFile().get().getAsFile()).exists(); assertThat(this.task.getArchiveFile().get().getAsFile()).exists();
@ -340,7 +340,7 @@ abstract class AbstractBootArchiveTests<T extends Jar & BootArchive> {
@Test @Test
void reproducibleOrderingCanBeEnabled() throws IOException { void reproducibleOrderingCanBeEnabled() throws IOException {
this.task.setMainClassName("com.example.Main"); this.task.getMainClass().set("com.example.Main");
this.task.from(newFile("bravo.txt"), newFile("alpha.txt"), newFile("charlie.txt")); this.task.from(newFile("bravo.txt"), newFile("alpha.txt"), newFile("charlie.txt"));
this.task.setReproducibleFileOrder(true); this.task.setReproducibleFileOrder(true);
executeTask(); executeTask();
@ -360,7 +360,7 @@ abstract class AbstractBootArchiveTests<T extends Jar & BootArchive> {
@Test @Test
void devtoolsJarIsExcludedByDefault() throws IOException { void devtoolsJarIsExcludedByDefault() throws IOException {
this.task.setMainClassName("com.example.Main"); this.task.getMainClass().set("com.example.Main");
this.task.classpath(newFile("spring-boot-devtools-0.1.2.jar")); this.task.classpath(newFile("spring-boot-devtools-0.1.2.jar"));
executeTask(); executeTask();
assertThat(this.task.getArchiveFile().get().getAsFile()).exists(); assertThat(this.task.getArchiveFile().get().getAsFile()).exists();
@ -372,7 +372,7 @@ abstract class AbstractBootArchiveTests<T extends Jar & BootArchive> {
@Test @Test
@Deprecated @Deprecated
void devtoolsJarCanBeIncluded() throws IOException { void devtoolsJarCanBeIncluded() throws IOException {
this.task.setMainClassName("com.example.Main"); this.task.getMainClass().set("com.example.Main");
this.task.classpath(jarFile("spring-boot-devtools-0.1.2.jar")); this.task.classpath(jarFile("spring-boot-devtools-0.1.2.jar"));
this.task.setExcludeDevtools(false); this.task.setExcludeDevtools(false);
executeTask(); executeTask();
@ -384,7 +384,7 @@ abstract class AbstractBootArchiveTests<T extends Jar & BootArchive> {
@Test @Test
void allEntriesUseUnixPlatformAndUtf8NameEncoding() throws IOException { void allEntriesUseUnixPlatformAndUtf8NameEncoding() throws IOException {
this.task.setMainClassName("com.example.Main"); this.task.getMainClass().set("com.example.Main");
this.task.setMetadataCharset("UTF-8"); this.task.setMetadataCharset("UTF-8");
File classpathDirectory = new File(this.temp, "classes"); File classpathDirectory = new File(this.temp, "classes");
File resource = new File(classpathDirectory, "some-resource.xml"); File resource = new File(classpathDirectory, "some-resource.xml");
@ -405,7 +405,7 @@ abstract class AbstractBootArchiveTests<T extends Jar & BootArchive> {
@Test @Test
void loaderIsWrittenFirstThenApplicationClassesThenLibraries() throws IOException { void loaderIsWrittenFirstThenApplicationClassesThenLibraries() throws IOException {
this.task.setMainClassName("com.example.Main"); this.task.getMainClass().set("com.example.Main");
File classpathDirectory = new File(this.temp, "classes"); File classpathDirectory = new File(this.temp, "classes");
File applicationClass = new File(classpathDirectory, "com/example/Application.class"); File applicationClass = new File(classpathDirectory, "com/example/Application.class");
applicationClass.getParentFile().mkdirs(); applicationClass.getParentFile().mkdirs();

@ -65,7 +65,7 @@ class BootJarTests extends AbstractBootArchiveTests<BootJar> {
@Test @Test
void contentCanBeAddedToBootInfUsingCopySpecFromGetter() throws IOException { void contentCanBeAddedToBootInfUsingCopySpecFromGetter() throws IOException {
BootJar bootJar = getTask(); BootJar bootJar = getTask();
bootJar.setMainClassName("com.example.Application"); bootJar.getMainClass().set("com.example.Application");
bootJar.getBootInf().into("test").from(new File("build.gradle").getAbsolutePath()); bootJar.getBootInf().into("test").from(new File("build.gradle").getAbsolutePath());
bootJar.copy(); bootJar.copy();
try (JarFile jarFile = new JarFile(bootJar.getArchiveFile().get().getAsFile())) { try (JarFile jarFile = new JarFile(bootJar.getArchiveFile().get().getAsFile())) {
@ -76,7 +76,7 @@ class BootJarTests extends AbstractBootArchiveTests<BootJar> {
@Test @Test
void contentCanBeAddedToBootInfUsingCopySpecAction() throws IOException { void contentCanBeAddedToBootInfUsingCopySpecAction() throws IOException {
BootJar bootJar = getTask(); BootJar bootJar = getTask();
bootJar.setMainClassName("com.example.Application"); bootJar.getMainClass().set("com.example.Application");
bootJar.bootInf((copySpec) -> copySpec.into("test").from(new File("build.gradle").getAbsolutePath())); bootJar.bootInf((copySpec) -> copySpec.into("test").from(new File("build.gradle").getAbsolutePath()));
bootJar.copy(); bootJar.copy();
try (JarFile jarFile = new JarFile(bootJar.getArchiveFile().get().getAsFile())) { try (JarFile jarFile = new JarFile(bootJar.getArchiveFile().get().getAsFile())) {
@ -276,7 +276,7 @@ class BootJarTests extends AbstractBootArchiveTests<BootJar> {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private void addContent() throws IOException { private void addContent() throws IOException {
BootJar bootJar = getTask(); BootJar bootJar = getTask();
bootJar.setMainClassName("com.example.Main"); bootJar.getMainClass().set("com.example.Main");
File classesJavaMain = new File(this.temp, "classes/java/main"); File classesJavaMain = new File(this.temp, "classes/java/main");
File applicationClass = new File(classesJavaMain, "com/example/Application.class"); File applicationClass = new File(classesJavaMain, "com/example/Application.class");
applicationClass.getParentFile().mkdirs(); applicationClass.getParentFile().mkdirs();

@ -37,7 +37,7 @@ class BootWarTests extends AbstractBootArchiveTests<BootWar> {
@Test @Test
void providedClasspathJarsArePackagedInWebInfLibProvided() throws IOException { void providedClasspathJarsArePackagedInWebInfLibProvided() throws IOException {
getTask().setMainClassName("com.example.Main"); getTask().getMainClass().set("com.example.Main");
getTask().providedClasspath(jarFile("one.jar"), jarFile("two.jar")); getTask().providedClasspath(jarFile("one.jar"), jarFile("two.jar"));
executeTask(); executeTask();
try (JarFile jarFile = new JarFile(getTask().getArchiveFile().get().getAsFile())) { try (JarFile jarFile = new JarFile(getTask().getArchiveFile().get().getAsFile())) {
@ -48,7 +48,7 @@ class BootWarTests extends AbstractBootArchiveTests<BootWar> {
@Test @Test
void providedClasspathCanBeSetUsingAFileCollection() throws IOException { void providedClasspathCanBeSetUsingAFileCollection() throws IOException {
getTask().setMainClassName("com.example.Main"); getTask().getMainClass().set("com.example.Main");
getTask().providedClasspath(jarFile("one.jar")); getTask().providedClasspath(jarFile("one.jar"));
getTask().setProvidedClasspath(getTask().getProject().files(jarFile("two.jar"))); getTask().setProvidedClasspath(getTask().getProject().files(jarFile("two.jar")));
executeTask(); executeTask();
@ -60,7 +60,7 @@ class BootWarTests extends AbstractBootArchiveTests<BootWar> {
@Test @Test
void providedClasspathCanBeSetUsingAnObject() throws IOException { void providedClasspathCanBeSetUsingAnObject() throws IOException {
getTask().setMainClassName("com.example.Main"); getTask().getMainClass().set("com.example.Main");
getTask().providedClasspath(jarFile("one.jar")); getTask().providedClasspath(jarFile("one.jar"));
getTask().setProvidedClasspath(jarFile("two.jar")); getTask().setProvidedClasspath(jarFile("two.jar"));
executeTask(); executeTask();
@ -72,7 +72,7 @@ class BootWarTests extends AbstractBootArchiveTests<BootWar> {
@Test @Test
void devtoolsJarIsExcludedByDefaultWhenItsOnTheProvidedClasspath() throws IOException { void devtoolsJarIsExcludedByDefaultWhenItsOnTheProvidedClasspath() throws IOException {
getTask().setMainClassName("com.example.Main"); getTask().getMainClass().set("com.example.Main");
getTask().providedClasspath(newFile("spring-boot-devtools-0.1.2.jar")); getTask().providedClasspath(newFile("spring-boot-devtools-0.1.2.jar"));
executeTask(); executeTask();
try (JarFile jarFile = new JarFile(getTask().getArchiveFile().get().getAsFile())) { try (JarFile jarFile = new JarFile(getTask().getArchiveFile().get().getAsFile())) {
@ -83,7 +83,7 @@ class BootWarTests extends AbstractBootArchiveTests<BootWar> {
@Test @Test
@Deprecated @Deprecated
void devtoolsJarCanBeIncludedWhenItsOnTheProvidedClasspath() throws IOException { void devtoolsJarCanBeIncludedWhenItsOnTheProvidedClasspath() throws IOException {
getTask().setMainClassName("com.example.Main"); getTask().getMainClass().set("com.example.Main");
getTask().providedClasspath(jarFile("spring-boot-devtools-0.1.2.jar")); getTask().providedClasspath(jarFile("spring-boot-devtools-0.1.2.jar"));
getTask().setExcludeDevtools(false); getTask().setExcludeDevtools(false);
executeTask(); executeTask();
@ -100,7 +100,7 @@ class BootWarTests extends AbstractBootArchiveTests<BootWar> {
orgDirectory.mkdir(); orgDirectory.mkdir();
new File(orgDirectory, "foo.txt").createNewFile(); new File(orgDirectory, "foo.txt").createNewFile();
getTask().from(webappDirectory); getTask().from(webappDirectory);
getTask().setMainClassName("com.example.Main"); getTask().getMainClass().set("com.example.Main");
executeTask(); executeTask();
try (JarFile jarFile = new JarFile(getTask().getArchiveFile().get().getAsFile())) { try (JarFile jarFile = new JarFile(getTask().getArchiveFile().get().getAsFile())) {
assertThat(jarFile.getEntry("org/")).isNotNull(); assertThat(jarFile.getEntry("org/")).isNotNull();
@ -110,7 +110,7 @@ class BootWarTests extends AbstractBootArchiveTests<BootWar> {
@Test @Test
void libProvidedEntriesAreWrittenAfterLibEntries() throws IOException { void libProvidedEntriesAreWrittenAfterLibEntries() throws IOException {
getTask().setMainClassName("com.example.Main"); getTask().getMainClass().set("com.example.Main");
getTask().classpath(jarFile("library.jar")); getTask().classpath(jarFile("library.jar"));
getTask().providedClasspath(jarFile("provided-library.jar")); getTask().providedClasspath(jarFile("provided-library.jar"));
executeTask(); executeTask();

@ -7,5 +7,5 @@ plugins {
applicationName = 'custom' applicationName = 'custom'
bootJar { bootJar {
mainClassName = 'com.example.ExampleApplication' mainClass = 'com.example.ExampleApplication'
} }

@ -5,5 +5,5 @@ plugins {
} }
bootJar { bootJar {
mainClassName = 'com.example.ExampleApplication' mainClass = 'com.example.ExampleApplication'
} }

@ -5,5 +5,5 @@ plugins {
} }
bootJar { bootJar {
mainClassName = 'com.example.ExampleApplication' mainClass = 'com.example.ExampleApplication'
} }

@ -5,5 +5,5 @@ plugins {
} }
bootWar { bootWar {
mainClassName = 'com.example.ExampleApplication' mainClass = 'com.example.ExampleApplication'
} }

@ -5,5 +5,5 @@ plugins {
} }
bootJar { bootJar {
mainClassName = 'com.example.ExampleApplication' mainClass = 'com.example.ExampleApplication'
} }

@ -5,5 +5,5 @@ plugins {
} }
bootWar { bootWar {
mainClassName = 'com.example.ExampleApplication' mainClass = 'com.example.ExampleApplication'
} }

@ -4,7 +4,7 @@ plugins {
} }
bootJar { bootJar {
mainClassName = 'com.example.Application' mainClass = 'com.example.Application'
classifier = 'boot' classifier = 'boot'
} }

@ -4,7 +4,7 @@ plugins {
} }
bootWar { bootWar {
mainClassName = 'com.example.Application' mainClass = 'com.example.Application'
classifier = 'boot' classifier = 'boot'
} }

@ -4,7 +4,7 @@ plugins {
} }
bootJar { bootJar {
mainClassName = 'com.example.Application' mainClass = 'com.example.Application'
layered { layered {
application { application {
intoLayer("static") { intoLayer("static") {

@ -4,7 +4,7 @@ plugins {
} }
bootJar { bootJar {
mainClassName = 'com.example.Application' mainClass = 'com.example.Application'
} }
repositories { repositories {

@ -4,7 +4,7 @@ plugins {
} }
bootJar { bootJar {
mainClassName = 'com.example.Application' mainClass = 'com.example.Application'
} }
repositories { repositories {

@ -4,7 +4,7 @@ plugins {
} }
bootJar { bootJar {
mainClassName = 'com.example.Application' mainClass = 'com.example.Application'
} }
repositories { repositories {

@ -4,7 +4,7 @@ plugins {
} }
bootJar { bootJar {
mainClassName = 'com.example.CustomMain' mainClass = 'com.example.CustomMain'
duplicatesStrategy = "exclude" duplicatesStrategy = "exclude"
} }

@ -4,7 +4,7 @@ plugins {
} }
bootJar { bootJar {
mainClassName = 'com.example.Application' mainClass = 'com.example.Application'
} }
repositories { repositories {

@ -4,7 +4,7 @@ plugins {
} }
bootJar { bootJar {
mainClassName = 'com.example.Application' mainClass = 'com.example.Application'
} }
repositories { repositories {

@ -8,7 +8,7 @@ sourceSets {
} }
bootJar { bootJar {
mainClassName = 'com.example.Application' mainClass = 'com.example.Application'
} }
repositories { repositories {

@ -10,7 +10,7 @@ subprojects {
} }
bootJar { bootJar {
mainClassName = 'com.example.Application' mainClass = 'com.example.Application'
layered { layered {
application { application {
intoLayer("static") { intoLayer("static") {

@ -4,7 +4,7 @@ plugins {
} }
bootJar { bootJar {
mainClassName = 'com.example.Application' mainClass = 'com.example.Application'
preserveFileTimestamps = false preserveFileTimestamps = false
reproducibleFileOrder = true reproducibleFileOrder = true
} }

@ -4,7 +4,7 @@ plugins {
} }
bootJar { bootJar {
mainClassName = 'com.example.Application' mainClass = 'com.example.Application'
if (project.hasProperty('includeLaunchScript') ? includeLaunchScript : false) { if (project.hasProperty('includeLaunchScript') ? includeLaunchScript : false) {
launchScript { launchScript {
properties 'prop' : project.hasProperty('launchScriptProperty') ? launchScriptProperty : 'default' properties 'prop' : project.hasProperty('launchScriptProperty') ? launchScriptProperty : 'default'

@ -4,7 +4,7 @@ plugins {
} }
bootWar { bootWar {
mainClassName = 'com.example.Application' mainClass = 'com.example.Application'
} }
repositories { repositories {

@ -4,7 +4,7 @@ plugins {
} }
bootWar { bootWar {
mainClassName = 'com.example.Application' mainClass = 'com.example.Application'
} }
repositories { repositories {

@ -4,7 +4,7 @@ plugins {
} }
bootWar { bootWar {
mainClassName = 'com.example.Application' mainClass = 'com.example.Application'
} }
repositories { repositories {

@ -4,7 +4,7 @@ plugins {
} }
bootWar { bootWar {
mainClassName = 'com.example.Application' mainClass = 'com.example.Application'
preserveFileTimestamps = false preserveFileTimestamps = false
reproducibleFileOrder = true reproducibleFileOrder = true
} }

@ -4,7 +4,7 @@ plugins {
} }
bootWar { bootWar {
mainClassName = 'com.example.Application' mainClass = 'com.example.Application'
if (project.hasProperty('includeLaunchScript') ? includeLaunchScript : false) { if (project.hasProperty('includeLaunchScript') ? includeLaunchScript : false) {
launchScript { launchScript {
properties 'prop' : project.hasProperty('launchScriptProperty') ? launchScriptProperty : 'default' properties 'prop' : project.hasProperty('launchScriptProperty') ? launchScriptProperty : 'default'

@ -5,7 +5,7 @@ plugins {
} }
bootJar { bootJar {
mainClassName = 'com.example.Application' mainClass = 'com.example.Application'
} }
group = 'com.example' group = 'com.example'

@ -5,7 +5,7 @@ plugins {
} }
bootWar { bootWar {
mainClassName = 'com.example.Application' mainClass = 'com.example.Application'
} }
group = 'com.example' group = 'com.example'

@ -5,7 +5,7 @@ plugins {
} }
bootJar { bootJar {
mainClassName = 'com.example.Application' mainClass = 'com.example.Application'
} }
group = 'com.example' group = 'com.example'

@ -5,7 +5,7 @@ plugins {
} }
bootWar { bootWar {
mainClassName = 'com.example.Application' mainClass = 'com.example.Application'
} }
group = 'com.example' group = 'com.example'

@ -4,7 +4,7 @@ plugins {
} }
springBoot { springBoot {
mainClassName = 'com.example.CustomMainClass' mainClass = 'com.example.CustomMainClass'
} }
task echoMainClassName { task echoMainClassName {

Loading…
Cancel
Save